异常处理
struts1.1以前的版本中Struts应用程序的异常处理与大多数其他应用程序一样,在代码中需要用try/catch语句处理每个异常。但如果多个地方需要进行相同的异常处理则会产生代码冗余。struts1.1提供了很小但非常有效的声明式异常处理机制。
配置异常处理:
可以创建全局性的异常处理程序定义和针对某个操作的处理程序定义。定义中用type属性指定要处理的异常,用key属性指定资源束中关于此异常的一条信息,用path指定该异常发生时要转至的页面。举例如下:
struts-config.xml:
<action-mappings >
<action
attribute="myExceptionForm"
input="/exception/failure.jsp"
name="myExceptionForm"
path="/myException"
scope="request"
type="com.yourcompany.struts.action.exception.MyExceptionAction"
validate="true">
<exception
key="error.exception.length"
path="/exception/exception.jsp"
type="com.yourcompany.struts.exception.LengthException" />
<forward name="success" path="/exception/success.jsp" />
<forward name="failure" path="/excpetion/failure.jsp" />
</action>
</action-mappings>
com.yourcompany.struts.action.exception.MyExceptionAction.java:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception{
MyExceptionForm myExceptionForm = (MyExceptionForm) form;// TODO Auto-generated method stub
String phoneNumber = myExceptionForm.getPhoneNumber();
if(phoneNumber.length()<4){
return mapping.getInputForward();
}
if(phoneNumber.length()!=11){
throw new com.yourcompany.struts.exception.LengthException();
}else return mapping.findForward("success");
}
}
LengthException类只需简单声明:
package com.yourcompany.struts.exception;
public class LengthException extends Exception {
}
处理流程:
我们来看看RequestProcess如何处理异常的:
org.apache.struts.action.RequestProcessor.java:
public void process(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
...
ActionForward forward =
processActionPerform(request, response,
action, form, mapping);
...
}
...
processActionPerform(HttpServletRequest request,
HttpServletResponse response,
Action action,
ActionForm form,
ActionMapping mapping)
throws IOException, ServletException {
try {
return (action.execute(mapping, form, request, response));
} catch (Exception e) {
return (processException(request, response,
e, form, mapping));
}
}
...
HttpServletResponse response,
Exception exception,
ActionForm form,
ActionMapping mapping)
throws IOException, ServletException {
ExceptionConfig config = mapping.findException(exception.getClass());
if (config == null) {
log.warn(getInternal().getMessage("unhandledException",
exception.getClass()));
if (exception instanceof IOException) {
throw (IOException) exception;
} else if (exception instanceof ServletException) {
throw (ServletException) exception;
} else {
throw new ServletException(exception);
}
}
try {
ExceptionHandler handler = (ExceptionHandler)
RequestUtils.applicationInstance(config.getHandler());
return (handler.execute(exception, config, mapping, form,
request, response));
} catch (Exception e) {
throw new ServletException(e);
}
}
分析:
声明式异常发生在action类的execute()方法中,RequestProcessor捕捉该方法抛出的异常。收到异常时,执行processException()方法,进行异常处理,处理结果是一个ActionForward,表示转至的页面,然后返回ActionForward,process方法结束,应用程序跳到ActionForward指定的页面继续运行。
porcessException()方法的具体步骤如下:
1. 查找action元素中的exception元素,得到代表此exception元素的ExceptionConfigd对象实例config
若config为空,说明action元素没有配置响应的exception元素,此时,如果action抛出的错误为IOException,则RequestProcessor抛出IOException,否则RequestProcessor抛出ServletException错误,Tomcat5.0.30服务器下的页面显示如下:
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException
org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:523)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
root cause
com.yourcompany.struts.exception.LengthException
com.yourcompany.struts.action.exception.MyExceptionAction.execute(MyExceptionAction.java:46)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
note The full stack trace of the root cause is available in the Apache Tomcat/5.0.30 logs.
________________________________________
Apache Tomcat/5.0.30
若config不为空,则根据config生成异常处理器类ExcdptionHandler,该处理器执行execute()方法,该方法创建一个ActionError,将其存储至适当的作用域并返回一个与exception元素的path属性相关的ActionForward对象。总的来说,如果在action元素中声明一个exception元素,并发生了与其相应的异常,则异常控制器将创建一个ActionError并存储到适当的作用域,然后跳转到exception元素的path属性指定的页面。
处理器类ExcdptionHandler默认为org.apache.struts.action.ExceptionHandler,也可由exception元素的handler指定一个org.apache.struts.action.ExceptionHandler的子类,该子类必须重写execute()方法以定义操作。举例如下:
package com.yourcompany.struts.extend;
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.ExceptionHandler;
import org.apache.struts.config.ExceptionConfig;
public class MyExceptionHandler extends ExceptionHandler {
@Override
public ActionForward execute(Exception arg0, ExceptionConfig arg1, ActionMapping arg2, ActionForm arg3, HttpServletRequest arg4, HttpServletResponse arg5) throws ServletException {
//定义自己的操作
// ...
return super.execute(arg0, arg1, arg2, arg3, arg4, arg5);
}
}
评论