我有一个 spring 应用程序,它公开了在 CXF 中实现的 REST API。我正在尝试实现长轮询,为此我使用了AsyncResponse和Suspended。如果我在 tomcat(maven 插件或独立)中运行这段代码,它就可以工作。但是,如果我使用 maven 插件 (mvn jetty:run) 在码头运行相同的代码,它会失败。CXF 抛出 NPE。我已经对其进行了调试,发现没有为请求设置 ContinuationProvider。因此,在进一步调试中,我发现 jetty 在应用过滤器之前在内部将 Request 对象中的 AsyncSupport 布尔变量设置为 false,然后在 finally 块中再次将其设置为 true。但是过滤器链也包含 servlet,因此导致 servlet 以 AsyncSupport 为假来解释请求。
来自码头代码库的码头 maven 插件版本 9.1.3vxxxxxx ServletHandler.java
@Override
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException
{
final Request baseRequest=(request instanceof Request)?((Request)request):HttpChannel.getCurrentHttpChannel().getRequest();
// pass to next filter
if (_filterHolder!=null)
{
if (LOG.isDebugEnabled())
LOG.debug("call filter " + _filterHolder);
Filter filter= _filterHolder.getFilter();
if (_filterHolder.isAsyncSupported())
filter.doFilter(request, response, _next);
else
{
final boolean suspendable=baseRequest.isAsyncSupported();
if (suspendable)
{
try
{
baseRequest.setAsyncSupported(false);
filter.doFilter(request, response, _next);
}
finally
{
baseRequest.setAsyncSupported(true);
}
}
else
filter.doFilter(request, response, _next);
}
return;
}
为什么过滤器链包含 servlet ?为什么 reuest 在 doFilter 之前开始修改?如何让它在 jetty maven 插件中工作?