2011-04-21 54 views
11

我将Struts 2配置为将任何java.lang.Exception重定向到记录异常的特殊Action。我的重定向工作,但我的行动总是得到一个空的异常(即使当我明确地抛出一个异常)。这里是我的struts.xml文件:将Struts 2异常处理程序映射到Action

<global-results> 
    <result name="errHandler" type="chain"> 
    <param name="actionName">errorProcessor</param> 
    </result> 
</global-results> 

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

<action name="errorProcessor" class="myErrorProcessor"> 
     <result name="error">/error.jsp</result> 
</action> 

<action name="throwExceptions" class="throwExceptions"> 
     <result name="success">done.jsp</result> 
</action> 

在我的错误处理,我有以下几点:

public class myErrorProcessor extends ActionSupport { 

    private Exception exception; 

    public String execute() { 
     System.out.println("null check: " + (exception == null)); 
     return "error"; 
    } 

    public void setException(Exception exception) { 
     this.exception = exception; 
    } 

    public Exception getException() { 
     return exception; 
    } 
} 

在throwsException类,我有以下几点:

public String execute() { 
    int x = 7/0; 
    return "success"; 
} 

当我运行我的程序,异常处理程序总是得到一个空异常。我正在使用链类型重定向到异常处理程序。我是否需要实现某种ExceptionAware接口? Struts 2异常setter是否调用setException之外的东西?

注意:我在编写这个程序时试图关注this tutorial

+0

我提供了一个重复链接教程的行为,但是它包含全部所需的所有文件以减少错误的可能性。 – Quaternion 2012-04-29 18:07:25

回答

4

我遇到了同样的问题!

尽管Struts填充exception字段更清晰,但看起来该字段没有发生(如您所述)。为了解决这个问题,我从我的异常处理类中删除异常场(和其的getter/setter)(您myErrorProcessor类),取而代之的是用一种方法来“手动”提取从ValueStack异常:

/** 
* Finds exception object on the value stack 
* 
* @return the exception object on the value stack 
*/ 
private Object findException() {   
    ActionContext ac = ActionContext.getContext(); 
    ValueStack vs = ac.getValueStack(); 
    Object exception = vs.findValue("exception");  

    return exception; 
} 

然后,我可以使用instanceof来确保例外Object是我期待的类型,然后相应地处理该异常(如将定制的Exception对象中的消息写入数据库)。

让我知道这是如何适合你的! :)

+0

适合我。谢谢! – 2013-05-30 05:24:44

6

使用struts2版本2.3.1.2我没有得到一个null异常在我的错误处理程序中一切工作如广告。确保您使用的是未经修改的defaultStack。

就可信来源而言,我们可以参考ExceptionMappingInterceptorChaining Interceptor的拦截文档。 ExceptionMappingInterceptor将一个ExceptionHolder推送到值栈上,该栈栈反过来暴露一个异常属性。链式拦截器将值栈上的所有属性复制到目标。由于ExceptionHolder在堆栈中,如果有一个异常setter它将被设置。

这里是所有生产工作示例文件:

struts.xml中(保持相当类似的问题):

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE struts PUBLIC 
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 
"http://struts.apache.org/dtds/struts-2.3.dtd"> 

<struts> 
    <constant name="struts.devMode" value="true" /> 
    <constant name="struts.ui.theme" value="simple" /> 
    <package name="kenmcwilliams" namespace="/" extends="struts-default"> 
     <global-results> 
      <result name="errHandler" type="chain"> 
       <param name="actionName">errorProcessor</param> 
      </result> 
     </global-results> 
     <global-exception-mappings> 
      <exception-mapping exception="java.lang.Exception" result="errHandler" /> 
     </global-exception-mappings> 
     <action name="errorProcessor" class="com.kenmcwilliams.test.myErrorProcessor"> 
      <result name="error">/WEB-INF/content/error.jsp</result> 
     </action> 
     <action name="throwExceptions" class="com.kenmcwilliams.kensocketchat.action.Bomb"> 
      <result name="success">/WEB-INF/content/bomb.jsp</result> 
     </action> 
    </package> 
</struts> 

MyErrorProcessor.java

package com.kenmcwilliams.test; 

import com.opensymphony.xwork2.ActionSupport; 

public class MyErrorProcessor extends ActionSupport { 

    private Exception exception; 

    @Override 
    public String execute() { 
     System.out.println("Is exception null: " + (exception == null)); 
     System.out.println("" 
       + exception.getMessage()); 
     return "error"; 
    } 

    public void setException(Exception exceptionHolder) { 
     this.exception = exceptionHolder; 
    } 

    public Exception getException() { 
     return exception; 
    } 
} 

炸弹(刚刚抛出RuntimeException):

package com.kenmcwilliams.kensocketchat.action; 

import com.opensymphony.xwork2.ActionSupport; 

public class Bomb extends ActionSupport{ 
    @Override 
    public String execute() throws Exception{ 
     throw new RuntimeException("Hello from Exception!"); 
    } 
} 

查看炸弹(/ WEB-INF/content/bomb。JSP)永远无法到达]

<%@taglib prefix="s" uri="/struts-tags"%> 
<%@page contentType="text/html" pageEncoding="UTF-8"%> 
<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>The Bomb!</title> 
    </head> 
    <body> 
     <h1>The Bomb!</h1> 
    </body> 
</html> 

查看有关错误(/WEB-INF/content/error.jsp)

<%@taglib prefix="s" uri="/struts-tags"%> 
<%@page contentType="text/html" pageEncoding="UTF-8"%> 
<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>Global Error Handler</title> 
    </head> 
    <body> 
     <h1>Global Error Handler</h1> 
     <s:property value="exception.stackTrace"/> 
    </body> 
</html> 

输出:

我看到error.jsp页面渲染和我在glassfish控制台上看到以下内容:

INFO: Is exception null: false 
INFO: Hello from Exception! 
+1

完整的代码很好的解释!奇迹般有效。谢谢 ! – Saurabh 2013-01-28 20:22:29