本文介紹了攔截器拋出的異常不會(huì)轉(zhuǎn)到異常處理程序。的處理方法,對(duì)大家解決問(wèn)題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧!
問(wèn)題描述
今天我遇到了一個(gè)問(wèn)題。我有一個(gè)攔截器,它開(kāi)始并提交Hibernate事務(wù),它可能在提交時(shí)拋出異常(例如org.hibernate.StaleObjectStateException
)。也就是說(shuō),它可以?huà)伋霎惓#惓2粫?huì)到達(dá)處理程序。我以為我的代碼有問(wèn)題。但后來(lái)我寫(xiě)了一個(gè)簡(jiǎn)單的測(cè)試,結(jié)果是
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,控制臺(tái)輸出:
test logic
exception catched in interceptor, rethrowing java.lang.RuntimeException: qwerty
但如果BusinessLogic拋出異常,我們可以取消對(duì)代碼的注釋?zhuān)?/p>
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
我們將看到錯(cuò)誤頁(yè)面。
那么,有沒(méi)有人能很好地解釋這種行為呢?如果異常攔截器不能處理其他攔截器拋出的異常,那么將異常攔截器放在默認(rèn)Struts堆棧的頂部有什么意義?為什么??
如果您能給我一個(gè)好的答復(fù),我將不勝感激。
編輯:
有一個(gè)代碼我有問(wèn)題:
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()
引發(fā)的異常,該怎么辦?
推薦答案
該異常由TestInterceptor
在操作調(diào)用和結(jié)果呈現(xiàn)后引發(fā)。
來(lái)自Writing Interceptors page上的備注:
請(qǐng)記住,Invoke將在調(diào)用結(jié)果之后返回(例如。在呈現(xiàn)了您的JSP后),這使得它非常適合于打開(kāi)視圖中的會(huì)話(huà)模式之類(lèi)的東西。如果要在調(diào)用結(jié)果之前執(zhí)行某些操作,則應(yīng)實(shí)現(xiàn)PreResultListener。
這篇關(guān)于攔截器拋出的異常不會(huì)轉(zhuǎn)到異常處理程序。的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,