gpt4 book ai didi

java - 拦截器抛出的异常不会转到异常处理程序。

转载 作者:行者123 更新时间:2023-11-29 05:57:55 24 4
gpt4 key购买 nike

我今天遇到了一个问题。我有一个开始并提交 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");
}
}

所以,控制台输出:

test logic
exception catched in interceptor, rethrowing java.lang.RuntimeException: qwerty

但是如果 BusinnesLogic 抛出异常,我们可以取消注释代码:

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 上的注释:

Keep in mind that invoke will return after the result has been called (eg. after you JSP has been rendered), making it perfect for things like open-session-in-view patterns. If you want to do something before the result gets called, you should implement a PreResultListener.

关于java - 拦截器抛出的异常不会转到异常处理程序。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11335328/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com