在xwork中,package的定义中增加了global-exception-mappings,action的定义中增加了 exception-mapping,要想使用这2个特性,
必须使用xwork-1.1.dtd才行 .
DTD中,
global-exception-mappings是这样定义 的,
<
ELEMENT global-exception-mappings (exception-mapping+)
>
也就是说如果要使用,至少包含一个异常映射.
exception-mapping的定义 如下:
<!ELEMENT exception-mapping (#PCDATA|param)*>
<!ATTLIST exception-mapping
name CDATA #IMPLIED
exception CDATA #REQUIRED
result CDATA #REQUIRED
>
<!ATTLIST exception-mapping
name CDATA #IMPLIED
exception CDATA #REQUIRED
result CDATA #REQUIRED
>
可以看到 有3个属性:名称,异常类型,和结果.
经过一番查看,发现xwork-default.xml中还没有定义相关的拦截器,搜索了一下,发现了 ExceptionMappingInterceptor , 看来它是把异常翻译为相应的结果的.
(在最后发行版本中,应该会定义的.目前只好我们自己定义了.)
首先我们虚拟一个程序,假设程序会抛出几种程序
Action定义如下 :
package com.jscud.ww2test.exceptionmap;
import com.opensymphony.xwork.ActionSupport;
/**
* @author scud [url]http://www.jscud.com[/url]
*
*/
public class ExpMappingAction extends ActionSupport
{
private int type;
public String execute() throws NoRightException,NotFoundException
{
if (type==1)
{
throw new NoRightException();
}
else if (type ==99)
{
throw new NotFoundException();
}
else if (type==60) //其他异常
{
throw new IllegalArgumentException();
}
return SUCCESS;
}
public int getType()
{
return type;
}
public void setType( int type)
{
this .type = type;
}
}
import com.opensymphony.xwork.ActionSupport;
/**
* @author scud [url]http://www.jscud.com[/url]
*
*/
public class ExpMappingAction extends ActionSupport
{
private int type;
public String execute() throws NoRightException,NotFoundException
{
if (type==1)
{
throw new NoRightException();
}
else if (type ==99)
{
throw new NotFoundException();
}
else if (type==60) //其他异常
{
throw new IllegalArgumentException();
}
return SUCCESS;
}
public int getType()
{
return type;
}
public void setType( int type)
{
this .type = type;
}
}
从Action可以看出,程序至少会抛出3种异常,我们如果使用异常映射,就要考虑到抛出的所有异常.
程序中用到的NoRightException,NotFoundException是为了演示而建立的2个简单异常,无任何特殊代码,继承自 Exception.
我们的
Xwork.xml中的定义 如下:
<
package
name
="exceptionmapping"
extends
="webwork-default"
namespace
="/exceptionmap"
>
< interceptors >
< interceptor name ="exceptionmapping" class ="com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor" />
< interceptor-stack name ="myDefaultStack" >
< interceptor-ref name ="defaultStack" />
< interceptor-ref name ="exceptionmapping" />
</ interceptor-stack >
</ interceptors >
< default-interceptor-ref name ="myDefaultStack" />
< global-results >
< result name ="noright" type ="dispatcher" >
< param name ="location" > /exceptionmap/noright.jsp </ param >
</ result >
< result name ="exception" type ="dispatcher" >
< param name ="location" > /exceptionmap/exception.jsp </ param >
</ result >
</ global-results >
< global-exception-mappings >
< exception-mapping name ="noright" exception ="com.jscud.ww2test.exceptionmap.NoRightException" result ="noright" />
< exception-mapping name ="exception" exception ="java.lang.Exception" result ="exception" />
</ global-exception-mappings >
< action name ="index" class ="com.jscud.ww2test.exceptionmap.ExpMappingAction" >
< exception-mapping name ="notfound" exception ="com.jscud.ww2test.exceptionmap.NotFoundException" result ="notfound" />
< result name ="success" type ="dispatcher" >
< param name ="location" > /exceptionmap/index.jsp </ param >
</ result >
< result name ="notfound" type ="dispatcher" >
< param name ="location" > /exceptionmap/notfound.jsp </ param >
</ result >
</ action >
</ package >
< interceptors >
< interceptor name ="exceptionmapping" class ="com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor" />
< interceptor-stack name ="myDefaultStack" >
< interceptor-ref name ="defaultStack" />
< interceptor-ref name ="exceptionmapping" />
</ interceptor-stack >
</ interceptors >
< default-interceptor-ref name ="myDefaultStack" />
< global-results >
< result name ="noright" type ="dispatcher" >
< param name ="location" > /exceptionmap/noright.jsp </ param >
</ result >
< result name ="exception" type ="dispatcher" >
< param name ="location" > /exceptionmap/exception.jsp </ param >
</ result >
</ global-results >
< global-exception-mappings >
< exception-mapping name ="noright" exception ="com.jscud.ww2test.exceptionmap.NoRightException" result ="noright" />
< exception-mapping name ="exception" exception ="java.lang.Exception" result ="exception" />
</ global-exception-mappings >
< action name ="index" class ="com.jscud.ww2test.exceptionmap.ExpMappingAction" >
< exception-mapping name ="notfound" exception ="com.jscud.ww2test.exceptionmap.NotFoundException" result ="notfound" />
< result name ="success" type ="dispatcher" >
< param name ="location" > /exceptionmap/index.jsp </ param >
</ result >
< result name ="notfound" type ="dispatcher" >
< param name ="location" > /exceptionmap/notfound.jsp </ param >
</ result >
</ action >
</ package >
首先定义了一个exceptionmapping拦截器,用来指向ExceptionMappingInterceptor.
然后定义 一个拦截器Stack,包含defaultStack和exceptionmapping,注意,exceptionmapping是在Stack的最后 面,否则会发生不可预期的结果.
然后定义 一个拦截器Stack,包含defaultStack和exceptionmapping,注意,exceptionmapping是在Stack的最后 面,否则会发生不可预期的结果.
可以看到global-exception-mappings段包含了2个异常映射,一个为NoRight的处理,另外一个为对应 java.lang.Exception的映射.
在Action的定义中包含了一个exception-mapping,对应NotFound异常.
没有看到IllegalArgumentException的对应结果?? 拦截器对没有定义的异常会依次找这个异常的父类,一级一级向上查找,例如IllegalArgumentException的最终父节点是 Exception,就会转向到Exception对应的结果. 如果一个异常有多个层次关系上的父类,那个关系最近就找谁.
演示页面 如下:
<%@ page contentType="text/html; charset=GBK" %>
<%@ taglib uri="webwork" prefix="ww" %>
<html>
<head>
<title>exception mapping</title>
</head>
<body>
<br>
Exception 1:
<a href="index.jspa?type=1">Exception 1</a>
<br><br>
Exception 99:
<a href="index.jspa?type=99">Exception 99</a>
<br><br>
Other Exception:
<a href="index.jspa?type=60">Exception 60</a>
<br><br>
Normal:
<a href="index.jspa">No Exception</a>
<br><br>
</body>
</html>
<%@ taglib uri="webwork" prefix="ww" %>
<html>
<head>
<title>exception mapping</title>
</head>
<body>
<br>
Exception 1:
<a href="index.jspa?type=1">Exception 1</a>
<br><br>
Exception 99:
<a href="index.jspa?type=99">Exception 99</a>
<br><br>
Other Exception:
<a href="index.jspa?type=60">Exception 60</a>
<br><br>
Normal:
<a href="index.jspa">No Exception</a>
<br><br>
</body>
</html>
jsp页面的异常显示:其中AddException,DaoException,FindException是自己定义的异常,继承 exception
<%@ page language=
"java" contentType=
"text/html; charset=GB18030"
pageEncoding= "GB18030" %>
<%@ taglib prefix= "ww" uri= "/webwork" %>
<%@ page import = "com.opensymphony.xwork.util.OgnlValueStack" %>
<%@ page import = "com.opensymphony.xwork.ActionContext" %>
<%@ page import = "com.opensymphony.xwork.interceptor.ExceptionHolder" %>
<%@ page import = "com.mdcl.framework.exception.*" %>
<%@ page import = "java.io.*" %>
<%@ page import = "com.mdcl.timecard.util.Translate" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030" >
<title>Insert title here</title>
</head>
<body>
异常信 息
<%
String tipMessge = null ;//中文提示信息
OgnlValueStack s = ActionContext.getContext().getValueStack();
ExceptionHolder e;
String s1 = new String("");;
String name = new String("");
for (int i = s.size();i>0;i--){
Object obj = s.pop();
if (obj instanceof ExceptionHolder){
e = (ExceptionHolder)obj;
Object o = e.getException();
if (o instanceof AddException){
AddException we = (AddException)o;
tipMessge = Translate.translate("ErrorException" );
}else if (o instanceof DaoException){
DaoException we = (DaoException)o;
tipMessge = Translate.translate("ErrorException" );
}
else if (o instanceof FindException){
FindException we = (FindException)o;
tipMessge = Translate.translate("ErrorException" );
}
s1 =e.getExceptionStack();
System.out.println(tipMessge);
break ;
}
}
OutputStream b = response.getOutputStream();
%>
<br/>
<%=tipMessge%>
<%=s1%>
</body>
</html>
pageEncoding= "GB18030" %>
<%@ taglib prefix= "ww" uri= "/webwork" %>
<%@ page import = "com.opensymphony.xwork.util.OgnlValueStack" %>
<%@ page import = "com.opensymphony.xwork.ActionContext" %>
<%@ page import = "com.opensymphony.xwork.interceptor.ExceptionHolder" %>
<%@ page import = "com.mdcl.framework.exception.*" %>
<%@ page import = "java.io.*" %>
<%@ page import = "com.mdcl.timecard.util.Translate" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030" >
<title>Insert title here</title>
</head>
<body>
异常信 息
<%
String tipMessge = null ;//中文提示信息
OgnlValueStack s = ActionContext.getContext().getValueStack();
ExceptionHolder e;
String s1 = new String("");;
String name = new String("");
for (int i = s.size();i>0;i--){
Object obj = s.pop();
if (obj instanceof ExceptionHolder){
e = (ExceptionHolder)obj;
Object o = e.getException();
if (o instanceof AddException){
AddException we = (AddException)o;
tipMessge = Translate.translate("ErrorException" );
}else if (o instanceof DaoException){
DaoException we = (DaoException)o;
tipMessge = Translate.translate("ErrorException" );
}
else if (o instanceof FindException){
FindException we = (FindException)o;
tipMessge = Translate.translate("ErrorException" );
}
s1 =e.getExceptionStack();
System.out.println(tipMessge);
break ;
}
}
OutputStream b = response.getOutputStream();
%>
<br/>
<%=tipMessge%>
<%=s1%>
</body>
</html>