一、处理一般异常(javaBean异常)

     struts2进行异常处理首先需要添加exception拦截器,而默认拦截器栈已经加入了这个拦截器,所以不用特意的声明。在Struts 2框架中,采用声明式异常处理方式。在这种方式下,只需要在struts.xml文件中进行配置,Struts 2便能够处理异常,并跳转到相应的视图,而在Action中无须编写任何异常处理代码。

如果Action在处理请求的过程中出现异常,一个名称为exception的拦截器将拦截该异常,并进行处理。所以在struts.xml文件中,需要对exception拦截器进行配置。


1.配置元素

在struts.xml文件中,使用元素,对exception拦截器进行异常映射配置,该元素有以下两个属性:
exception 该属性用来指定出现异常的类型。
result 该属性用来指定出现异常时,Struts 2返回给用户的视图名称。

2.异常映射分类

根据异常映射作用的范围,可以将异常映射配置分为以下两类:

A、全局异常映射

作用范围是package中的所有Action。这种映射使用元素进行配置,在该元素中嵌套作为子元素。

例如:

<package name="error-handler" extends="struts-default">

    <global-results>
            <result name="noPoint">/page/common/noPoint.jsp</result>

            <result name="noMethod">/page/common/noMethod.jsp</result>

            <result name="exception">/page/common/exception.jsp</result>

            <result name="error" type="chain">exceptionHandler</result>
            <result name="input
">/page/common/inputError.jsp</result>
            <result name="success">/page/common/resData.jsp</result>
            <!-- error handler page -->
            <result name="errAjax">/page/common/appError.jsp</result>
            <result name="errPage">/page/common/exceptionPage.jsp</result>
        </global-results>

<global-exception-mappings>

    <exception-mapping result="nullPoint"

exception="java.lang.NullPointerException"/>


<exception-mapping result="noMethod"

exception="java.lang.NoSuchMethodException"/>


<exception-mapping result="exception"

exception="java.lang.Exception"/>

</global-exception-mappings>

</package>

B、局部异常映射

作用范围是配置元素所在的Action。这种映射是在Action内部,使用元素进行配置。

例如:

<action name="login" class="action.LoginAction">

    <exception-mapping result="nullPoint"

exception="java.lang.NullPointerException"/>

    <result name="success">/welcome.jsp</result>

    <result name="nullPoint">/nullpoint.jsp</result>

</action>

这两种异常映射的优先级不同,当两种映射有冲突时,局部映射将覆盖全局异常映射。

###################注意#########################

注意:

当异常发生时,struts2会根据抛出的异常去异常映射文件中寻找在继承关系上与该异常最接近的映射进行匹配。 例如,action抛出一个IOException,这个异常是Exception的直接子类。所以会匹配到Exception映射。再者,action 抛出一个BatchUpdateException,它既是SQLException的子类,同时也是Exception的子类。但是它和 SQLException的继承关系最接近,所以它会匹配到SQLException。

<struts>
    <package name="default">
        ...
        <global-results>
            <result name="login" type="redirect">/Login.action</result>
            <result name="Exception">/Exception.jsp</result>
        </global-results>

        <global-exception-mappings>
            <exception-mapping exception="java.sql.SQLException" result="SQLException"/>
            <exception-mapping exception="java.lang.Exception" result="Exception"/>
        </global-exception-mappings>
        ...
        <action name="DataAccess" class="com.company.DataAccess">
            <exception-mapping exception="com.company.SecurityException" result="login"/>
            <result name="SQLException" type="chain">SQLExceptionAction</result>
            <result>/DataAccess.jsp</result>
        </action>
        ...
    </package>
</struts>

说明:全局异常也只有在package包下进行配置,只对下面的action起作用,在struts没有如struts中那样的异常。局部异常和全局异常的搭配使用。

用三个例子说明,当访问DataAccess时如果发生异常
一个java.sql.SQLException将会chain到另一个action SQLExceptionAction
一个 com.company.SecurityException 将会重定向到Login.action
任何其他继承了java.lang.Exception 的异常将会转至Exception.jsp
¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
值栈中的Exception值:

默认情况下,发生异常时,struts2会向值栈中压入一下两个值:

exception : 异常对象本身
exceptionStack :stack trace的值

 ##在jsp页面我们可以使用<s:debug></s:debug>来查看值栈信息,也可以使用标签:

      <s:property value="exception.message"/>

      <s:property value="exceptionStack"/>输出异常信息和异常堆栈信息

到了这里我们可以知道了,有时我们为什么可以在拦截器中能够得到异常对象了吧:

            HttpServletRequest request = ServletActionContext.getRequest();
                //获取异常
                Exception ex = (Exception) request.getAttribute("exception");

或者

          ActionContext context = actionInvocation.getInvocationContext().getContext();
                ValueStack stack = context.getValueStack();

                Exception ex = (Exception) stack.findValue("exception")

看到上面的两段代码你会怀疑exception对象时什么时候存放到值栈中和request中的呢???呵呵,其实就是在发生异常的时候struts2向值栈中和request域中存放的!!!!!

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

在jsp中可以打印出异常信息
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>系统异常</title>
  </head>
  <body>
    <h3>出错信息,请与管理员联系</h3>
<s:actionerror/>
<p>
  <s:property value="%{exception.message}"/>

<%--<s:property value="exception.MyExceptionMsg"/>(其中MyExceptionMsg是我们自定义异常中的一个属性(一定要提供get和set方法)) --%>
</p>
<h3>详细信息</h3>
<p>
  <s:property value="%{exceptionStack}"/>

<s:debug></s:debug>可以查看值栈信息
</p>
  </body>
</html>


###################注意#############################

C、处理不存在的Action

  只需在struts.xml中加:

   <default-action-ref name="defaultAction" />
<action name="defaultAction" class="com.lsw.permission.action.DefaultAction" />

 

3.输出异常信息

可以使用Struts 2中的property标签,输出异常信息。

输出异常对象本身,代码如下:

<s:property value="exception.message"/>

或者
<s:property value="exception.MyExceptionMsg"/>

(其中MyExceptionMsg是我们自定义异常中的一个属性(一定要提供get和set方法))

输出异常堆栈信息,代码如下:

<s:property value="exceptionStack"/>

例如sql.jsp页面

  <body>
   <s:property value="exception.message"/>
 </body>
 
二、.处理不存在的页面,如不存在的JSP,html,htm等页面(404异常)
,struts是不能处理这个异常的,还有其他异常(如500,401等等)都交给tomcat来处理,只需在web.xml中加如下配置即可:
   <!-- 处理不存在的页面 -->
<error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/jsp/error/404.jsp</location>
</error-page>
<!-- 处理500异常 -->
<error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/jsp/error/500.jsp</location>
</error-page>