综述
异常映射 是一个处理抛出异常的Action的强大特性. 这个思想的核心是捕捉到Action的方法执行期间抛出的异常,并把它映射到一个result, 既可以是全局的也可以是action作用域内的results. 这对框架尤其有用, 比如Hibernate和Acegisecurity抛出的RuntimeExceptions.
为了和WebWork的其他部分协作,开启异常映射功能需要一个拦截器. 下面的代码片断是来自webwork-default.xml的,其中已经启用了异常映射.
...
<interceptors>
...
<interceptor name="exception" class="com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor"/>
...
</interceptors>
<interceptor-stack name="basicStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="servlet-config"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="static-params"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
</interceptor-stack>
...
异常处理的下一步就是映射实际的异常到特定的result.WebWork提供了两种方式来声明一个异常映射 <exception-mapping/> - 全局的或者针对一个特定的action. 异常映射元素有两个属性,exception 和 result.
当声明一个异常映射时,拦截器会根据抛出的异常来查找声明中的层次关系最接近的类.拦截器会检查此Action所有可用的声明的映射,包括Action特定的和全局的映射.result(全局或者Action范围的)然后会被调用.
这遵从一个Action返回一个result的一般规则. 它首先查看Action中的result定义, 当没有找到时查看全局的result定义.
下面的例子是一个全局和Action作用域内的异常映射的例子.
<xwork>
<package name="default">
...
<global-results>
<result name="login" type="redirect">/login.action</result>
<result name="rootException" type="freemarker">/WEB-INF/views/exception.ftl</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.sql.SQLException" result="sqlException"/>
<exception-mapping exception="java.lang.Exception" result="rootException"/>
</global-exception-mappings>
...
<action name="myAction" class="...">
<interceptor-ref name="exception" />
<exception-mapping exception="com.acme.foo.SecurityException" result="login"/>
<result name="sqlException" type="chain">sqlExceptionAction</result>
<result name="success" type="freemarker">/WEB-INF/views/acme/success.ftl</result>
</action>
...
</package>
</xwork>
在上面的例子中, 基于每一个异常的发生处理如下:
- 一个 java.sql.SQLException 将链接到 sqlExceptionAction
- 一个 com.acme.foo.SecurityException 将转向到 /login.action
- 任何其他继承于 java.lang.Exception 的异常将执行FreeMarker类型的result rootException ,显示页面 /WEB-INF/views/exception.ftl
ValueStack中的异常值(Exception Values on the ValueStack)
缺省情况下异常映射拦截器(ExceptionMappingInterceptor)添加下列值到Value Stack中:
- exception - 异常对象自己
- exceptionStack - 异常堆栈