struts2异常处理:
Struts2提供了很多拦截器,这里也提供了异常处理的拦截器,已经在struts-default.xml中配置好了,我们只需要声明式应用即可,Action方法抛出的异常能够被自动捕获然后经过映射指向一个预定义好的Result。
<interceptors> <interceptor name=”exception” class="com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor"/> </interceptors>
Struts2提供了两种异常声明类型:全局和局部异常
全局:
<global-exception-mappings> <!--当Action遇到Exception异常时,系统将转入global-result对应的逻辑视图中 --> <exception-mapping result="sql" exception="java.sql.SQLException"></exception-mapping> <exception-mapping result="root" exception="java.lang.Exception"></exception-mapping> </global-exception-mappings>
局部:
<!--当Action遇到Exception异常时,系统将转入action中的result对应的逻辑视图中 --> <action name="login" class="action.LoginAction"> <result name="my">/exception.jsp</result> <!-- 定义局部异常映射 --> <exception-mapping result="my" exception="util.MyException"></exception-mapping> </action>
在strust.xml中配置了异常映射后,在程序中,我们只需一级级向上抛出异常,那么当程序执行,出现对应的异常,则会根据配置的异常匹配来跳入相应的异常信息页面,在页面上,我们可以使用:
<s:property value=exception.message/>这是输出异常信息(throw new RuntimeException(“出现了异常”)中的构造参数)
<s:property value=exceptionStack/>输出异常堆栈信息
strut2的异常处理方便了很多,而在其之前的1版本呢,就没这么方便了……
struts1异常处理:
struts1的异常处理有手动方式、自动方式(不能解决多个参数,不能异常多个异常)、自定义统一的异常类(推荐),笔者就针对第三种方式做一个讲解。
使用自定义的异常类来继承原始的异常。用自定义的异常类来处理整个工程的异常。在一个异常类中使用多种异常。用一个异常类来代表不同的异常消息。
首先,定义自己的异常类:他要继承RuntimeException:
package edu.hust.util; import java.io.PrintStream; import java.io.PrintWriter; public class SystemException extends RuntimeException { private String key; private Object[] values; public String getKey(){ return key; } public Object[] getValues(){ return values; } public SystemException() { super(); } public SystemException(String message, Throwable cause) { super(message, cause); } public SystemException(String message) { super(message); } public SystemException(Throwable cause) { super(cause); } public SystemException(String message,String key){ super(message); this.key = key; } public SystemException(String message,String key,Object values){ super(message); this.key = key; this.values = new Object[]{values}; } public SystemException(String message,String key,Object[] values){ super(message); this.key = key; this.values = values; } }
当struts截取异常时,会交给handler所指定的类来处理,handler在配置文件中需要配置,默认的是org.apache.struts.action.ExceptionHandler,但是struts的默认的Handler不能处理我们自定义的异常类(大家可以将我们自己定义的异常类和RuntimeException源码做个简单对比),因为里面有其他的属性,因此我们需要自定义一个handler类来专门处理我们定义统一的异常类。
package edu.hust.util; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ExceptionHandler; import org.apache.struts.config.ExceptionConfig; public class SystemExceptionHandler extends ExceptionHandler { @Override public ActionForward execute(Exception ex, ExceptionConfig ae, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws ServletException { ActionForward forward = null; if( null != ae.getPath()){ forward = new ActionForward(ae.getPath());//获得默认的path }else{ forward = mapping.getInputForward(); } if(ex instanceof SystemException){ //处理自定义的异常类 ActionMessage error = null; SystemException sysExce = (SystemException) ex; String key = sysExce.getKey(); //获得key if( null == key){ //如果可以为空 error = new ActionMessage(ae.getKey(),sysExce.getMessage()); }else{ if(null != sysExce.getValues()){ // 可以不为空,且有参数 error = new ActionMessage(key,sysExce.getValues()); }else{ error = new ActionMessage(key); } } this.storeException(request, key, error, forward, ae.getScope()); return forward; } return super.execute(ex, ae, mapping, formInstance, request, response); //异常不属于自定义异常类 } }
Exception Handling,有了它就不需要我们用try/catch等捕获异常,一旦出现了我们已经定义的异常那么就会转到相应得页面,并且携带定制的信息。
剩下的至于如何在struts-config.xml中配置和错误信息展示页面,在此就不再赘述了。
总之 Struts框架处理异常的流程
struts的控制器负责捕获各种异常,包括控制器运行中本身抛出的异常,以及调用模型的业务方法时抛出的异常。当struts的控制器捕获到异常后,在异常处理代码块中,创建描述信息的actionmessage对象把它保存在acionmessages(或其子类actionerrors)对象中,然后把ACTIONMESSAGES保存在特定范围(配置文件中的scope)。然后可以用<html:errors>检索特定范围内的actionmessages对象。