2011-04-21 31 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