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

Struts2 interceptor (After View Rendered Interceptor ) is not called before the redirect request comes back from browser

在 Web 应用程序中,我们使用 struts2 拦截器进行事务管理

拦截器的伪代码

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

当操作 returns 'redirect' (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:

在上面的日志中Task-37(线程)假设save/update数据库中的一些记录并发出重定向以刷新视图,其拦截器将提交事务。

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

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

提前致谢。

这是一个工作代码,类似于 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();
}