在Struts2中支持声明式异常处理
-
抛出
一般我们处理异常是在后台抛出或者捕获
如在上一个BBS中,我们的service包的中CategoryService在处理实现数据库的操作时有很多异常,如在增加方法中用try-catch方法进行捕获,那出现异常就会在日志里,在控制台,而反应不到我们前台输出
//增加
public void add(Category c){
Connection con=DB.getConn();
String sql="insert into _category values (null,?,?);";
PreparedStatement ps=DB.getStatement(con, sql);
try {
ps.setString(1,c.getName());
ps.setString(2,c.getDescription());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
DB.close(ps);
DB.close(con);
}
那么在struts里是支持声明异常处理,就是后天一旦有异常就抛出来,在action里给一个统一的接口,显示在特定的jsp页面,所以我们修改add方法,在e.printStackTrace();后抛出throw(e);下面抛出所以在方法开始就要throws SQLException
//增加
public void add(Category c) throws SQLException {
Connection con=DB.getConn();
String sql="insert into _category values (null,?,?);";
PreparedStatement ps=DB.getStatement(con, sql);
try {
ps.setString(1,c.getName());
ps.setString(2,c.getDescription());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
throw(e);
}
DB.close(ps);
DB.close(con);
}
这样我们在Action类中调用add方法也要处理异常,这里我们也要抛出交给struts2来处理,这里我们抛出Exception,这样struts2就可以处理所有申明的异常
public String add() throws Exception {
categoryservice.add(c);
return SUCCESS;
}
这里可以参考我们经常在Action类中重写ActionSupport的excute()方法,它也是抛出所有异常,这样所有重写它的方法都会抛出异常交给struts2处理
ActionSupport的excute()方法源码
重写必须抛出
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return super.execute();
}
好,那我们抛出要怎么处理呢
-
处理异常
首先当然是配置struts.xml文件,为action配置exception-mapping参数,若是匹配到对应的异常就返回error,转到error的result,显示error.jsp文件
<package name="admin" namespace="/admin" extends="struts-default">
<action name="*_*" class="xidian.lili.bbs.action.{1}Action" method="{2}">
<result>/admin/{1}_{2}.jsp</result>
<result name="input">//admin/{1}_{2}.jsp</result>
<exception-mapping result="error" exception="java.sql.SQLException"></exception-mapping>
<result name="error">/error.jsp</result>
</action>
</package>
-
测试
这时候在action类中执行add的action会受到抛出的sql异常,就会跳转到error.jsp,用debug标签查看值栈内容,发现struts2将异常压入值栈 ,这样我们也可以去到异常,显示在jsp页面
-
多个action的异常处理
上面我们只针对能匹配到 *_* 的action做了异常,那么我们有多个action有申明异常要处理的时候,如果在每个action没面配置exception-mapping太麻烦,就采用下面的方式
我们专门定义一个package,处理异常,配置global-exception-mappings参数,全局异常,然后在其他包中的action处理异常时就可以继承异常处理的package,然后如果每个action有自己的异常jsp要显示就可以配置自己的error result,否则定义global-result。转到error.jsp
-
struts2处理声明异常原理
利用拦截器 ,在接受到一个请求,首先struts的filter过滤,然后交给拦截器,最后交给action处理
那么我们看异常处理拦截器,默认拦截器引用是defaultStack
<default-interceptor-ref name="defaultStack"/>
那么查看defaultStack内容,有这么多拦截器,第一个就是exception,也就是请求经过struts2的filter会被这么多拦截器处理,在交给action
exception interceptor的配置如下
<interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
是在xwork中处理的