首先在struts2中有两种异常处理机制:局部异常映射和全局异常映射。
拿经典的用户登录功能来说:
一:局部异常:
1:首先我们的登录界面:表单交由exAction.action 处理。
<span style="font-family:KaiTi_GB2312;font-size:18px;"><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@taglib prefix="s" uri="/struts-tags" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <s:form action="exAction" id="form" method="post"> <s:textfield name="username" key="user"/> <s:textfield name="password" key="pass"/><br/> <s:submit key="login"/> </s:form> </body> </html>:</span>
2:我们先定义一个异常myException:申明message属性并提供get,set方法,封装提示信息。该类继承Exception
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.mao; public class myException extends Exception { private String message; public myException(String message) { super(message); this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }</span>3:然后我们的逻辑控制器Action,实现类:ExceptionAction
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.mao; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class ExceptionAction extends ActionSupport{ private String username; private String password; private String tip; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getTip() { return tip; } public void setTip(String tip) { this.tip = tip; } public String execute()throws Exception{ ActionContext act=ActionContext.getContext(); if(getUsername().equalsIgnoreCase("user")){ throw new myException("自定义异常"); } if(getUsername().equalsIgnoreCase("sql")){ throw new java.sql.SQLException("用户名不能为sql"); } if(getUsername().equals("mao")&&getPassword().equals("3214")){ setTip("服务器提示:登陆成功"); return SUCCESS; }else{ return ERROR; } } } </span>代码很明显看出,如果用户名为user抛出自定义异常,如果为sql抛出系统定义的SQLException异常,这里顺便说一下equalsIgnoreCase()方法与equals()区别,从字面上也看出来了equalsIgnoreCase()字面不拘小节嘛,所以它不区分大小写,比如用户名getUsername.equalsIgnoreCase("mao"),你输mao和Mao都是可以可以的,而equals()严格区分字节和长度,比较苛刻。
4:然后我们的配置文件struts.xml,此处我只列举出局部异常的部分:
<span style="font-family:KaiTi_GB2312;font-size:18px;"> <!-- 定义局部异常和局部结果集 --> <action name="exAction" class="com.mao.ExceptionAction"> <exception-mapping result="my" exception="com.mao.myException"/> <result name="my">/ecpt.jsp</result> <result name="success">/welcom.jsp</result> <result name="error">/error.jsp</result> </action></span>这里注意,局部异常是在<action></action>标签内通过<exception-mapping/>标签定义的的,而且需要指定结果字符串result="my",和exception="com.mao.myException"异常映射所指定的异常类型,拿此处来讲,映射的就是咱们前面定义的myException异常,com.mao为该类所在的包。可以看出,局部异常全部定义在<action></action>标签之内。一快看下来就是,前台表单交给exAction去处理,好,处理的过程中抛出了一个myException异常,然后该异常返回了一个my的结果字符串,然后,在下面<result name="my">/ecpt.jsp</result>标签中定义此异常所返回的视图。这里也可以发现struts2框架的优点,耦合度低,前台表单仅传过来一个action,然后核心控制器filet截获并匹配相应逻辑控制器action去处理,处理完成后不是直接用视图的形式显示出来,而是返回一个字符串my,然后再通过相应字符串映射到相应视图。这大大提高了代码的复用性,哪天我们需要映射到不同视图时,只需修改<result>映射就可以(好了,扯多了)
5:这是返回的ecpt.jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@taglib prefix="s" uri="/struts-tags" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> 异常信息:<s:property value="exception.message"/> </body> </html>
另外提示一点,本人在测试的时候由于在此页面中一直没有加
<%@taglib prefix="s" uri="/struts-tags" %>
6:结果
在表单输入user或者User
二:全局异常:
1:同样拿这个用户登录界面来讲,前面的表单,控制器exAction都已经给出,不再多说,我们直接看Struts.xml配置信息的如何配置全局异常:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;background-color: rgb(255, 255, 255);"> <!-- 定义全局结果映射 --> <global-results> <result name="sql">/ecpt.jsp</result> <result name="root">/ecpt.jsp</result> </global-results> <!-- 定义全局异常 --> <global-exception-mappings> <exception-mapping result="sql" exception="java.sql.SQLException"/> <exception-mapping result="root" exception="java.lang.Exception"/> </global-exception-mappings></span></span>
2:结果:我们分别输入sql和正确的用户名密码 mao 3214显示
三:总结:
局部异常映射只对该Action有效,全局异常映射对所有Action有效。
但是局部异常映射"执行力"强,在都局部异常和全局异常都定义了相同映射的情况,程序会先去局部映射寻找相应的<result name="">所返回的视图,如果有,返回该视图,如果没有,那好,去全局映射里找。
例如:
<global-results> <result name="my">/welcom.jsp</result> </global-results> <!-- 定义全局异常 --> <global-exception-mappings> <exception-mapping result="my" exception="com.mao.myException"/> </global-exception-mappings> <!-- 定义局部异常和局部结果集 --> <action name="exAction" class="com.mao.ExceptionAction"> <exception-mapping result="my" exception="com.mao.myException"/> </action>如上,我们在局部以及全局异常映射里都定义了com.mao.myException的映射,而且返回结果字符串都为my,程序会先去局部找,发现并没有找到相应的<result name="my">定义的返回视图,这时他就会去全局找,正好找到有个定义的<result name="my">所以将返回welcom.jsp页面,记住一句话:在局部映射和全局映射都存在相同<resule name="">属性,而且局部异常映射指定了jsp页面的情况下,全局映射永远都是"备胎"。