在重定向请求从浏览器返回之前,不会调用Struts2拦截器(After View Rendered Interceptor)

时间:2017-10-04 22:48:13

标签: struts2 interceptor

在webapp中,我们使用struts2拦截器进行事务管理

拦截器的伪代码

public String intercept(ActionInvocation invocation) throws Exception {
    TransactionService.startTransaction();
    invocation.invoke();
    TransactionService.commitTransaction();
}

当操作返回“重定向”(302)时,有时重定向的请求在调用“TransactionService.commitTransaction()”之前到达服务器。 (看起来网络调用比堆栈展开更快)

下面记录的日志消息解释了这个

2017-10-04 09:18:37,693 [task-37] DEBUG (interceptors)  TransactionInterceptor begin
2017-10-04 09:18:37,949 [task-38] DEBUG (interceptors)  TransactionInterceptor begin
2017-10-04 09:18:37,963 [task-37] DEBUG (interceptors)  TransactionInterceptor commit 
2017-10-04 09:18:37,955 [task-38] ERROR (interceptors)  SecurityInterceptor: Failed to execute Action:

在上面的日志中任务-37(线程)假设保存/更新DB中的一些记录并发出重定向来刷新视图,其拦截器将提交事务。

但重定向线程(Task-38)在提交之前到达了服务器。

我正在查看PreResultListener或'Chain Result'。 (两个选项都有自己的问题)我非常感谢解决这个问题的任何输入

提前致谢。

1 个答案:

答案 0 :(得分:0)

这是一个工作代码,与PreResultListener一起使用。

public String intercept(ActionInvocation invocation) throws Exception {
    invocation.addPreResultListener(new PreResultListener() {
        @Override
        public void beforeResult(ActionInvocation invocation, String resultCode) {
            try {

                // commit based on the resultCode comparision 
                if (StringUtils.equals(resultCode,"302_redirect")  {
                    TransactionService.commitTransaction();
                }
                // or commparision based on the redirect handler 
                // Class names are from struts-default.xml
                /*
                String resultConfigClassName = invocation.getProxy().getConfig().getResults().get(resultCode).getClassName();
                if (StringUtils.equals(resultConfigClassName,"org.apache.struts2.dispatcher.ServletRedirectResult")
                        || StringUtils.equals(resultConfigClassName, "org.apache.struts2.dispatcher.ServletActionRedirectResult")) {
                    TransactionService.commitTransaction();
                }
                */
            }
            catch (Exception e) {
                // Ignore don't do anything
            }
        }
    });

    TransactionService.startTransaction();
    invocation.invoke();
    TransactionService.commitTransaction();
}