本文介紹了攔截器拋出的異常不會轉到異常處理程序。的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
今天我遇到了一個問題。我有一個攔截器,它開始并提交Hibernate事務,它可能在提交時拋出異常(例如org.hibernate.StaleObjectStateException
)。也就是說,它可以拋出異常,但異常不會到達處理程序。我以為我的代碼有問題。但后來我寫了一個簡單的測試,結果是
struts.xml
中的包定義:
<package name="basicstruts2" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="dummy" class="test.TestInterceptor"/>
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="dummy" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"/>
<global-results>
<result name="exception" type="chain">exceptionHandler</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="exception" />
</global-exception-mappings>
<action name="test" class="test.TestAction">
<result>result.jsp</result>
</action>
<action name="exceptionHandler" class="test.ExceptionHandler">
<result>DebugErrorPage.jsp</result>
</action>
</package>
TestAction.java
:
package test;
public class TestAction extends ActionSupport {
private BusinessLogic logic = new BusinessLogic();
public String execute() {
logic.test();
return SUCCESS;
}
}
TestInterceptor.java
:
package test;
public class TestInterceptor implements Interceptor {
@Override
public String intercept(ActionInvocation arg0) throws Exception {
String result = null;
try {
result = arg0.invoke();
boolean flag = true;
if (flag) throw new RuntimeException("qwerty");
} catch (Exception e) {
System.out.println("exception catched in interceptor, rethrowing " + e);
throw e;
}
return result;
}
}
ExceptionHandler.java
:
package test;
public class ExceptionHandler extends ActionSupport {
private Exception exception;
public void setException(Exception e) {
exception = e;
System.out.println("setting exception");
}
public String execute() {
System.out.println("exeption in handler " + exception);
return SUCCESS;
}
}
BusinessLogic.java
:
package test;
public class BusinessLogic {
public void test() {
System.out.println("test logic");
// boolean flag = true;
// if (flag) throw new RuntimeException("qwerty");
}
}
so,控制臺輸出:
test logic
exception catched in interceptor, rethrowing java.lang.RuntimeException: qwerty
但如果BusinessLogic拋出異常,我們可以取消對代碼的注釋:
BusinessLogic.java
:
package test;
public class BusinessLogic {
public void test() {
System.out.println("test logic");
boolean flag = true;
if (flag) throw new RuntimeException("qwerty");
}
}
并注釋掉攔截器中的代碼:
@Override
public String intercept(ActionInvocation arg0) throws Exception {
String result = null;
try {
result = arg0.invoke();
// boolean flag = true;
// if (flag) throw new RuntimeException("qwerty");
} catch (Exception e) {
System.out.println("exception catched in interceptor, rethrowing " + e);
throw e;
}
return result;
}
輸出將為:
test logic
exception catched in interceptor, rethrowing java.lang.RuntimeException: qwerty
setting exception
exeption in handler java.lang.RuntimeException: qwerty
我們將看到錯誤頁面。
那么,有沒有人能很好地解釋這種行為呢?如果異常攔截器不能處理其他攔截器拋出的異常,那么將異常攔截器放在默認Struts堆棧的頂部有什么意義?為什么??
如果您能給我一個好的答復,我將不勝感激。
編輯:
有一個代碼我有問題:
public String intercept(ActionInvocation arg0) throws Exception {
String result = null;
try {
sf.getCurrentSession().beginTransaction();
result = arg0.invoke();
sf.getCurrentSession().getTransaction().commit();
} catch (StaleObjectStateException staleEx) {
if (sf.getCurrentSession().getTransaction().isActive()) {
sf.getCurrentSession().getTransaction().rollback();
}
throw staleEx;
} catch (Exception ex) {
ex.printStackTrace();
try {
if (sf.getCurrentSession().getTransaction().isActive()) {
sf.getCurrentSession().getTransaction().rollback();
}
} catch (Throwable rbEx) {
}
// Let others handle it... maybe another interceptor for exceptions?
throw new ServletException(ex);
}
return result;
}
如果我希望處理commit()
引發的異常,該怎么辦?
推薦答案
該異常由TestInterceptor
在操作調用和結果呈現后引發。
來自Writing Interceptors page上的備注:
請記住,Invoke將在調用結果之后返回(例如。在呈現了您的JSP后),這使得它非常適合于打開視圖中的會話模式之類的東西。如果要在調用結果之前執行某些操作,則應實現PreResultListener。
這篇關于攔截器拋出的異常不會轉到異常處理程序。的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,