Exception thrown by an interceptor doesn#39;t go to the exception handler.(拦截器抛出的异常不会转到异常处理程序。)
问题描述
今天我遇到了一个问题。我有一个拦截器,它开始并提交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。
这篇关于拦截器抛出的异常不会转到异常处理程序。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:拦截器抛出的异常不会转到异常处理程序。
				
        
 
            
        - Eclipse 的最佳 XML 编辑器 2022-01-01
 - 获取数字的最后一位 2022-01-01
 - 转换 ldap 日期 2022-01-01
 - 未找到/usr/local/lib 中的库 2022-01-01
 - java.lang.IllegalStateException:Bean 名称“类别"的 BindingResult 和普通目标对象都不能用作请求属性 2022-01-01
 - 如何使 JFrame 背景和 JPanel 透明且仅显示图像 2022-01-01
 - GC_FOR_ALLOC 是否更“严重"?在调查内存使用情况时? 2022-01-01
 - 将 Java Swing 桌面应用程序国际化的最佳实践是什么? 2022-01-01
 - 如何指定 CORS 的响应标头? 2022-01-01
 - 在 Java 中,如何将 String 转换为 char 或将 char 转换 2022-01-01
 
						
						
						
						
						
				
				
				
				