我有一个spring应用程序,它公开了在CXF中实现的REST API。我正在尝试实施长轮询,我使用了AsyncResponse以及Suspended。如果我在tomcat(maven插件或独立)中运行此代码,它可以工作。但是如果我使用maven插件(mvn jetty:run)在jetty中运行相同的代码,它就会失败。 CXF抛出NPE。我调试了它,发现没有为请求设置ContinuationProvider。因此,在进一步调试时,我发现jetty内部在应用过滤器之前将Request对象中的AsyncSupport布尔变量设置为false,然后在finally块设置中再次为true。但是过滤器链也包含servlet,因此导致servlet使用AsyncSupport false来解释请求。
jetty maven插件版本9.1.3vxxxxxx 来自jetty代码库的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? 为什么在doFilter之前开始修改reuest? 如何让它在jetty maven插件中运行?
答案 0 :(得分:0)
发现问题。它与Log4jServletContainerInitializer一起为所有请求自动注册过滤器(Log4jServletFilter)。这里的问题是我使用的版本。 Log4j2.0-beta-9(有问题),问题是当Log4jServletFilter注册时,它没有注册AsyncSupport(即async-supported true)。所以我升级到log4j2.0-rc1,解决了这个问题。 :)