異常處理: exception-mapping 元素
在action方法中添加
int i=1/0;
請求action後,結果爲:
在struts.xml中添加異常處理:exception-mapping元素
<action name="czy_save" class="com.qbz.struts2_02.GG_CZY" method="save">
<exception-mapping result="ArithmeticException" exception="java.lang.ArithmeticException"></exception-mapping>
<result name="ArithmeticException">/WEB-INF/page/Input.jsp</result>
<result name="save">/WEB-INF/page/Show.jsp</result>
</action>
此時,頁面將直接跳轉到Input.jsp:
在Input.jsp加入標籤顯示exception信息:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<form action="czy_save.action" method="post">
<s:debug></s:debug><br>
<s:property value="exception"/><br>
<s:property value="exception.message"/><br>
編號:<input type="text" name="dlh"/><br>
姓名:<input type="text" name="name"/><br>
部門:<input type="text" name="bmmc"/><br>
<input type="submit" value="保存"/>
</form>
</body>
</html>
請求action後的頁面效果:
點擊 Debug :
可見,對象棧的 棧頂 是異常對象,所以在上面頁面沒用下標就直接讀取屬性。ExceptionHolder有兩個屬性,一個是exceptionStack,一個是exception。
我們來看,Struts2是如何做到異常映射處理的。
在struts_default.xml中查看:
我們的package的父類struts-default中引用的默認攔截器
<default-interceptor-ref name="defaultStack"/>
ctrl+shift+t 查看 ExceptionMappingInterceptor 源碼
public class ExceptionMappingInterceptor extends AbstractInterceptor {
//省略......
@Override
public String intercept(ActionInvocation invocation) throws Exception {
String result;
try {
result = invocation.invoke();
} catch (Exception e) {
if (isLogEnabled()) {
handleLogging(e);
}
List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
ExceptionMappingConfig mappingConfig = this.findMappingFromExceptions(exceptionMappings, e);
if (mappingConfig != null && mappingConfig.getResult()!=null) {
Map parameterMap = mappingConfig.getParams();
// create a mutable HashMap since some interceptors will remove parameters, and parameterMap is immutable
invocation.getInvocationContext().setParameters(new HashMap<String, Object>(parameterMap));
result = mappingConfig.getResult();
publishException(invocation, new ExceptionHolder(e));
} else {
throw e;
}
}
return result;
}
//省略......
/**
* Default implementation to handle ExceptionHolder publishing. Pushes given ExceptionHolder on the stack.
* Subclasses may override this to customize publishing.
*
* @param invocation The invocation to publish Exception for.
* @param exceptionHolder The exceptionHolder wrapping the Exception to publish.
*/
protected void publishException(ActionInvocation invocation, ExceptionHolder exceptionHolder) {
invocation.getStack().push(exceptionHolder);
}
}
可見,當catch到異常之後publishException(invocation, new ExceptionHolder(e))把異常壓入了棧中。
每個action是不是都要配置異常處理呢?當然不用,下面來看global-exception-mappings、global-results 。
在struts.xml中配置如下:
<global-results>
<result name="ArithmeticException">/WEB-INF/page/Input.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="ArithmeticException" exception="java.lang.ArithmeticException"></exception-mapping>
</global-exception-mappings>