java - 如何创建多个异步 java 过滤器?

标签 java servlets asynchronous filter servlet-filters

我正在尝试创建一个具有多个异步过滤器的 Java 应用程序,但似乎无法让它们很好地协同工作。我认为主要问题出在 run() 方法中,我不知道如何将请求传递到链中的下一个过滤器。我试过chain.doFilter(request, response),但是好像不行,还有dispatch()complete() API 在 AsyncContext 上可用,但那些似乎关闭了整个 AsyncContext。似乎必须有另一种方法才能让它发挥作用。下面是我正在使用的过滤器的一个片段 - 第二个过滤器看起来几乎相同。

注意:我正在添加 header 以尝试找出正在调用的内容。

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
        final AsyncContext asyncContext = request.startAsync();
        final HttpServletResponse res = (HttpServletResponse) response;
        asyncContext.addListener(new AsyncListener() {
            @Override
            public void onComplete(AsyncEvent event) throws IOException {
                res.addHeader("S-AST2", "onComplete");
            }

            @Override
            public void onTimeout(AsyncEvent event) throws IOException {
                res.addHeader("S-AST3", "onTimeout");
            }

            @Override
            public void onError(AsyncEvent event) throws IOException {
                res.addHeader("S-AST4", "onError");
            }

            @Override
            public void onStartAsync(AsyncEvent event) throws IOException {
                res.addHeader("S-AST0", "onStartAsync");
            }
        });

        asyncContext.start(new Runnable() {
            @Override
            public void run() {
                res.addHeader("S-AST1", "before");
                // This doesn't seem to work...
                asyncContext.dispatch();
                // ... or this ...
                asyncContext.complete();
                // ... or this ...
                chain.doFilter(request, response);
            }
        });
    }

感谢您的任何见解!

最佳答案

这个答案有两个部分。

1) chain.doFilter(request, response); 仍然是必需的。

2) 这不起作用的原因是在每个过滤器和 servlet 中我调用了 request.startAsync(),它启动了一个异步进程,而不是使用现有的。因此,如果过滤器启动了一个异步进程,而 servlet 也启动了一个,它将覆盖/忽略过滤器中启动的进程。要解决此问题,您必须通过调用 request.isAsyncStarted() 检查异步进程是否已启动,如果已启动,您应该获取现有异步进程,而不是启动新的异步上下文使用 request.getAsyncContext()。下面是我为每个 servlet 和过滤器创建的帮助程序类,这样我就可以调用 AsyncHelper.getAsyncContext(request, response),它将检索现有的 AsyncContext,或者创建一个新的一个。

public class AsyncHelper {
    public static AsyncContext getAsyncContext(ServletRequest request, ServletResponse response) {
        AsyncContext asyncContext = null;
        if (request.isAsyncStarted()) {
            asyncContext = request.getAsyncContext();
        }
        else {
            asyncContext = request.startAsync(request, response);
            asyncContext.setTimeout(2000);
        }
        return asyncContext;
    }
}

关于java - 如何创建多个异步 java 过滤器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24746476/

相关文章:

java - 为所有 404 响应创建 servlet 过滤器

objective-c - 核心动画+核心音频+ sleep 未按预期顺序进行

java - 如何使用三层架构和 SQL Server 制作登录表单?

java - 如何将图像上传/下载到 GAE 数据存储中?

java - 方法签名内的@Validation

ios - 在 iOS 中重试 HTTP 请求

iphone - 当 dispatch_async 任务完成时如何通知我?

java - 创建基于 libreoffice 文本的数据源并使用 java 进行设置

iphone - 每秒向服务器发送验证请求(重复任务)

java - 即使 session 被破坏也获取旧 session 值