1 strtus2异常
在Action
中execute
方法声明为:public String execute() throws Exception
,这样,Action
可以抛出任何Exception
1.1 自己实现异常处理
我们以helloWorldAction
为例,在Action
的execute
方法中这样写:
public String execute() throws Exception {
int a=5/0;
this.businessExecute();
return "toWelcome";
}
上面的代码中有int a=5/0;
,很显然,会抛出除数为0
的错误,这个错误是RuntimeException
,我们的程序没有进行相应的例外处理,则会抛给Struts2
去处理。那么,在实际的项目中很显然不能这么简单而粗暴的处理错误,一种简单的处理方法就是跳转到一个错误处理页面。
假设要求这个Action
,在出现ArithmeticException
的时候,跳转到一个叫math-exception
的Result
,而其他错误跳转到另一个叫otherwise-exception
的Result
。那么,在Action
中可以这么写:
public String execute() throws Exception {
try {
int a = 5/0;
} catch (ArithmeticException e) {
e.printStackTrace();
return "math-exception";
} catch (Exception e){
e.printStackTrace();
return "otherwise-exception";
}
this.businessExecute();
return "success";
}
这样,在运行中出现ArithmeticException
就会跳转到math-exception
指定的页面,而其他Exception
就会跳转到otherwise-exception
指定的页面,如果没有出错,就会跳转到success
指定的页面。在struts.xml
的Action
中,只要配置好上述三个Result
就可以正常运行了。
1.2 Struts2的异常处理机制
1.2.1 局部异常映射
在<action>
元素中设置<exception-mapping>
元素,可以指定在execute
方法抛出指定错误的时候,跳转到哪个指定的页面。用Struts2
的异常机制就不需要自己手动去try-catch
了。action
里的代码如下:
public String execute() throws Exception {
int a=5/0;
this.businessExecute();
return "toWelcome";
}
然后在struts.xml
的<action>
元素中增加<exception-mapping>
子元素,示例如下:
<action name="helloworldAction" class="cn.javass.hello.struts2impl.action.HelloWorldAction">
<exception-mapping result="math-exception" exception="java.lang.ArithmeticException"/>
<exception-mapping result="math-exception" exception="java.lang.Exception"/>
<result name="math-exception">/${folder}/error.jsp</result>
<result name="toWelcome">/${folder}/welcome.jsp</result>
<result name="input">/${folder}/login.jsp</result>
</action>
在<action>
元素里面,增加了两个<exception-mapping>
元素,其execption
属性指定了一个Exception
的全类名,如果Action
的execute
方法抛出的错误是这个Exception
类的实例或其派生类的实例,则会跳转到对应的result
属性所指定的结果。当然,它们指定的名称为math-exception
的Result
,还是需要另行配置的。
1.2.2 全局异常映射
上面的<exception-mapping>
元素是作为<action>
元素的子元素来配置的,只对本<action>
元素有效。其实跟局部Result
和全局Result
一样,也可以把<exception-mapping>
提到父包中,做成全局的异常映射。
全局异常映射仍然是<exception-mapping>
元素,只不过不再是<action>
元素的子元素,而是<global-exception-mappings>
元素的子元素,而<global-exception-mappings>
元素是<package>
元素的子元素。当然,配置了<global-exception-mappings>
,自然需要配置<global-results>
注意:<global-results>
还必须在<global-exception-mappings>
之前,
示例如下:
<package name="helloworld" extends="struts-default">
<global-results>
<result name="math-exception">/${folder}/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="math-exception" exception="java.lang.ArithmeticException"/>
<exception-mapping result="math-exception" exception="java.lang.Exception"/>
</global-exception-mappings>
<action name="helloworldAction" class="cn.javass.hello.struts2impl.action.HelloWorldAction">
<result name="toWelcome">/${folder}/welcome.jsp</result>
<result name="input">/${folder}/login.jsp</result>
</action>
</package>
1.2.3 全局和局部比对
对比局部结果和全局结果的查找顺序,可以很容易的理解局部异常映射和全局异常映射的查找顺序:
首先,找自己的<action>
元素的内的<exception-mapping>
元素是否有匹配的,如果有就执行这个exception
的映射配置,如果没有,下一步。
其次,找自己的包里面的全局异常映射,也就是到自己的<action>
所在的package
中,找<global-exception-mappings >
元素内的< exception-mapping >
元素,看看是否有匹配的,如果有就执行这个exception
的映射配置,如果没有,下一步。
再次,递归的寻找自己的包的父包、祖父包中的全局异常映射是否有匹配的,如果有就执行这个exception
的映射配置,如果没有,下一步。
最后,如果上述三种情况都没有的话,则将Exception
抛出给Struts2
去处理。
注意
:如果出现同样符合条件的异常映射,上述的顺序也是异常映射之间的优先顺序,也就是说,如果Action
的execute
方法抛出一个异常,而局部异常映射和全局异常映射中都有相应的配置,那会以局部异常映射为准。
1.2.4 在页面输出异常信息
在前面的示例中,当Action
的execute
方法抛出一个异常之后,跳转到指定的页面,也就是error.jsp
后,并没有把具体的异常信息展示出来。那么,想要在error.jsp
页面上展示Exception
的错误信息,该怎么做呢?
可以使用Struts2
提供的标签,来输出Exception的错误信息,如下:<s:property value=”exception”/>
仅仅简单打印出exception
对象的例外消息。<s:property value=”exceptionStack”/>
可以打印出exception
的堆栈
信息。
error.jsp的页面如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ 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>
<font color=red><b>对不起,出错了,错误信息为:</b></font><br>
<s:property value="exception"/>
<br>
<font color=red><b>错误的堆栈信息为:</b></font><br>
<s:property value="exceptionStack"/>
</body>
</html>
按照上面的例子,会输出以下错误:
1 对不起,出错了,错误信息为:
2 java.lang.ArithmeticException: / by zero
3 错误的堆栈信息为:
4 java.lang.ArithmeticException: / by zero at cn.javass.hello.struts2impl.action.HelloWorldAction.execute(Hello)