Servlet 3.0中的Async-supported不起作用

25

这是我的web.xml文件

    <filter>
    <filter-name>pollingTest</filter-name>
    <filter-class>
        webapp.controller.core.servlet.PollingService
            </filter-class>
    <async-supported>true</async-supported>
</filter>
<filter-mapping>
    <filter-name>pollingTest</filter-name>
    <url-pattern>/app/poll</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>ASYNC</dispatcher>
</filter-mapping>

以下是这个类:

public class PollingService implements Filter {
Logger logger = LoggerFactory.getLogger(getClass());

@Override
public void destroy() {
    logger.info("Destroy");
}

@Override
public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {

    logger.info("Running");
    req.startAsync(req, res);
    this.doFilter(req, res, chain);
    return;
}

@Override
public void init(FilterConfig arg0) throws ServletException {

    logger.info("Init=");
}

}

我在Glassfish和Tomcat 7上运行它,但是遇到了异常:

java.lang.IllegalStateException: Request is within the scope of a filter or servlet that does not support asynchronous operations
at org.apache.catalina.connector.Request.startAsync(Request.java:3657)
at org.apache.catalina.connector.Request.startAsync(Request.java:3633)
at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:1053)
at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:450)

谁能帮助我解决这个问题?非常感谢。


请显示整个web.xml文件(至少包括<web-app>标签定义和命名空间)。 - Bozho
6个回答

52

因为您的servlet和链中的任何其他过滤器都必须在web.xml文件中具有<async-supported>true</async-supported>


如何使用注释来完成这个任务? - necromancer
10
@WebFilter(urlPatterns = "/*", asyncSupported = true) - necromancer
Netbeans 8.2 / Tomcat 8.0.27:我还必须禁用HTTP监视器(服务->服务器->右键单击Apache Tomcat->属性->取消选中启用HTTP监视器)。看起来这是一个错误 - albertamg

6

我有一个类似的问题,但在我的情况下不够。如果您使用标签Context和Valve(在tomcat7 - service.xml中),则必须在标记值中添加参数asyncSupported="true"。然后它就能正常工作了。

<Context docBase="aaa" path="/aaa" reloadable="true" source="org.eclipse.jst.jee.server:aaa"><Valve className="cz.tomcatUtil.ForceUserValve" user="DZC0GRP" asyncSupported="true"/></Context>

4

您正在递归调用this.doFilter(req, res, chain);

如果您想继续执行过滤器链,您必须调用chain.doFilter(httpRequest, httpResponse);而不是this.doFilter(req, res, chain);


3
您可以像这样使用注释来映射异步Servlet
@WebServlet(urlPatterns = {"/yourServlet"}, **asyncSupported=true**)

public class YourServlet extends HttpServlet { }

1

Peter Karabinovich,你的答案是不正确的。根据Servlet 3.0规范:

2.3.3.3 异步处理
...
允许从asyncSupported=true的servlet调度到其中一个asyncSupported设置为false的servlet。在这种情况下,当不支持异步处理的servlet的服务方法退出时,响应将被提交...


根据Servlet 4.0规范:“如果请求在不支持异步操作的servlet或过滤器的范围内,则调用startAsync是非法的...” - 62mkv

0

我知道这是一个旧帖子,但我想分享我的解决方案。因为我几乎尝试了所有可能的解决方案,所以花了我一周的时间才找到原因。

对我来说,servlet的url-pattern不正确。

<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/pattern/</url-pattern> <---
  </servlet-mapping>

希望它能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接