ITEEDU

Struts Gossip: 例外处理

Struts框架提供每一个 Action 对象处理自己例外的方法,只要使用<exception>标签在struts-config.xml中定义,例如:
...
 <action 
    path="/LoginAction" 
    type="onlyfun.caterpillar.LoginAction" 
    name="userForm" 
    input="/login.jsp"> 
    <exception 
        key="login.failure" 
        path="failure.jsp" 
        type="onlyfun.caterpillar.LoginFailureException"/> 
    <forward 
        name="greeting" 
        path="/greeting.jsp"/>
... 
key属性的设定是用来匹配讯息资源文件中的value值,如果在Action对象丢出type所指定的例外,将转送至path 属性所指定的页面,与例外相关的讯息会被封装在ActionErrors对象中,您可以在failure.jsp中使用<html: messages>来显示相关的错误讯息。

除了为每一个Action对象指定例外的处理,您也可以定义一个全局可匹配的例外,使用<global-exceptions>标签来进行声明:
... 
    <global-exceptions> 
        <exception 
            key="expired.password" 
            type="onlyfun.caterpillar.ExpiredPasswordException" 
            path="/changePassword.jsp"/> 
    </global-exceptions>
 ...
如果您想要深入了解Struts的例外处理方式,可以看看RequestProcessor原始码中的processException()方法,以及 ExceptionHandler的execute()方法。

当Action对象丢出例外时,RequestProcessor的processException()方法会看看是否有在< exception>标签中声明,这个工作是委由ActionMapping对象的findException()方法来执行,如果找不到相对应的 例外处理,除了标签中声明,这个工作是委由ActionMapping对象的findException()方法来执行,如果找不到相对应的例外处理,除 了IOException直接丢出之外,其它的例外则将之包装为ServletException例外再丢出:
ExceptionConfig config = 
          mapping.findException(exception.getClass()); 
 
if(config == null) { 
    .... 

    if(exception instanceof IOException) { 
        throws (IOException) exception; 
    } 
    else if(exception instanceof ServletException) { 
        throws (ServletException) exception; 
    } 
    else { 
        throws new ServletException(exception); 
    } 
}
如果RequestProcessor的processException()找到对应的例外处理,则加载ExceptionHandler进行处理,最后返回一个ActionForward对象:
Class handlerClass = Class.forName(config.getHandler()); 
ExceptionHandler handler = (ExceptionHandler) handlerClass.newInstance(); 
return (handler.execute(exception, config,
                        mapping, form,
                        request, response));