Struts2自定义异常处理拦截器出现问题

struts.xml:



    <global-results>
        <result name="error">error.jsp</result>
    </global-results>



<action name="insert" class="com.lul.action.InsertAction">
    <result name="success">success.jsp</result>
              <interceptor-ref name="exceptionInceptor"></interceptor-ref>
</action>

自定义异常类:
[code="java"]public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 1L;

public BusinessException(String errorMessage) {
    super(errorMessage);
}

}[/code]
自定义用于异常处理的拦截器:
public String intercept(ActionInvocation invocation) throws Exception {
String result = null;
try {
result = invocation.invoke();
} catch(DataAccessException dae) {
throw new BusinessException("数据库操作失败");
}
...
...捕获常见的异常,并以友好异常信息抛出
}
在调用insert.action后,dao抛出异常,但不知为什么不能跳到error.jsp页面,而是
[color=red]HTTP Status 500 -


type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: com.lul.exception.BusinessException: Sorry, 数据库操作失败 Please try again!
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:515)
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:419)[/color]

有哪位高手知道错误原因,请指教!

[b]问题补充:[/b]


error.jsp

    <global-exception-mappings>   
        <exception-mapping name="exceptionPage"  
                           exception="java.lang.Exception"  
                           result="exceptionPage"/>   
    </global-exception-mappings>  

这样是可以跳到error.jsp页面,但我想要的是在拦截器中对异常进行分类和包装,然后再以友好的方式提示到error.jsp
[b]问题补充:[/b]
to jones:
我是在exceptionInceptor拦截器里对异常进行分类,然后交给BusinessException去提示异常信息,不可能在Action里用N多的catch把异常分类吧,不知道有没有别的好的方法。
[b]问题补充:[/b]
to jones:
我明白你的意思,并且这样可以跳转到指定的错误页面,但我想请教一下,怎么能在错误页面获取拦截器里的异常提示信息。多谢!

[code="java"]怎么能在错误页面获取拦截器里的异常提示信息。多谢! [/code]
这个简单,通过ActionContext.getContext().getValueStack()拿到OGNL的ValueStack,把你的异常信息存进去,然后再页面通过OGNL表达式获取就行了

你的程序正常执行并返回"error"字符串的时候才会到error.jsp,如果你想在抛出任何异常的时候都到error.jsp,只能通过web.xml中进行配置,如下:
[code="java"]
404
/error.jsp


500
/error.jsp
[/code]

貌似global-exception-mappings应该个name对应到global-results

[code="xml"]
error.jsp

    <global-exception-mappings>
        <exception-mapping name="error"
                           exception="com.lul.exception.BusinessException"
                           result="error"/>
    </global-exception-mappings>[/code]

顺便说一句,你上面的这种情况明显是你的拦截器有问题

改成这样试试吧

[code="java"]
public String intercept(ActionInvocation invocation) throws Exception {
String result = null;
try {
result = invocation.invoke();
} catch(DataAccessException dae) {
//throw new BusinessException("数据库操作失败");//这里就别抛出了
return "error";
}
[/code]

全局异常配置和你的那个异常拦截器ExceptionMappingInterceptor没有必然联系,正常情况下

[code="java"]

error.jsp

    <global-exception-mappings>
        <exception-mapping name="exceptionPage"
                           exception="java.lang.Exception"
                           result="exceptionPage"/>
    </global-exception-mappings>

[/code]

就会拦截java.lang.Exception异常,转到error.jsp页面

你的友好的异常不就只的是你包装成BusinessException 吗??
[code="java"]

error.jsp

        <global-exception-mappings>  
            <exception-mapping name="exceptionPage"  
                               exception="java.lang.BusinessException"  
                               result="exceptionPage"/>  
        </global-exception-mappings>  [/code]

这样应该就可以了吧

晕!
[code="java"]exception="com.lul.exception.BusinessException"[/code]

那你的拦截器大概是这样的:
[code="java"]
@Override
public String intercept(ActionInvocation invocation) throws Exception {
try {
return invocation.invoke();
} catch (Exception e) {
exception(e);
return Action.ERROR;
}
}

private void exception(Exception e) throws Exception {
    if (e instanceof BusinessException) {
        BusinessException be = (BusinessException) e;
        //处理
    }
    if (e instanceof OtherException) {
        OtherException be = (OtherException) e;
        //处理
    } else {
        throw e;
    }
}

[/code]

xml文件配置你是对的

好的处理方法应该是这样的,如果你想把异常消息显示给用户看,那就抛出你定义的BusinessException异常,然后异常拦截器就只处理BusinessException异常,把异常转换成友好的消息传给用户,这样异常拦截器大概可以写成这样:

[code="java"]
public class ExceptionMappingInterceptor extends StaticParametersInterceptor {

@Override
public String intercept(ActionInvocation invocation) throws Exception {
    try {
        return invocation.invoke();
    } catch (Exception e) {
        ActionSupport actionSupport = (ActionSupport) invocation.getAction();
        exception(e, actionSupport);
        return Action.ERROR;
    }
}

private void exception(Exception e, ActionSupport actionSupport) throws Exception {
    if (e instanceof BusinessException) {
        BusinessException be = (BusinessException) e;
        String who = actionSupport.getText(be.getWho());
        String errorType = actionSupport.getText(be.getErrorType(), new String[]{who, be.getValue()});
        actionSupport.addActionError(errorType);
    } else {
        throw e;
    }
}

}
[/code]

就可以在页面展示给用户看了。

我可没说让你在Action中把异常分类,我还是那句话,拦截器中不要往外抛异常,一旦抛出了你就控制不了了,直接返回error字符串就OK了,导航到error.jsp用普通的导航规则,别走exception-mapping,这样你可以把异常信息放到你的拦截器中随意处理了

如果你在拦截器里面用这样的方式添加异常信息:

[code="java"]
actionSupport.addActionError("errorMeesage");

[/code]

在页面就可以这样展示:

[code="jsp"]<%@ page pageEncoding="UTF-8" %>
<%@ taglib uri="/struts-tags" prefix="s" %>


/s:if[/code]