mnd*_*mnd 7 java asynchronous servlets filter servlet-filters
我正在尝试创建具有多个异步过滤器的Java应用程序,但似乎无法使它们协同工作。我认为主要问题是在run()方法中,我不知道该如何将请求传递给链中的下一个过滤器。我已经尝试过chain.doFilter(request, response),但这似乎不起作用,并且上有dispatch()和complete()API可用AsyncContext,但是这些似乎封闭了整个AsyncContext。似乎必须有另一种方法来使它起作用。以下是我正在使用的过滤器的摘要-第二个过滤器看起来几乎相同。
注意:我正在添加标题以尝试弄清楚正在调用什么。
@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);
}
});
}
Run Code Online (Sandbox Code Playgroud)
感谢您的见解!
这个答案分为两部分。
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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4729 次 |
| 最近记录: |