Ben
Ben

Reputation: 1667

Servlet 3.0 Async-supported does not work

Here is my 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>

Here is the class:

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=");
}

}

I run it on glassfish and also on tomcat 7, got exception:

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)

Who can help me on this? thanks a lot.

Upvotes: 25

Views: 46410

Answers (6)

Greca
Greca

Reputation: 71

I had a similar problem, but in my case, it was not enough. If you use tags Context and Valve (in tomcat7 - service.xml), you must add parameter asyncSupported="true" in tag value. Then it had worked.

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

Upvotes: 6

Juan Ignacio
Juan Ignacio

Reputation: 906

You're calling recursively this.doFilter(req, res, chain);.

If you want continue the chain, you must invoke chain.doFilter(httpRequest, httpResponse); instead of this.doFilter(req, res, chain);.

Upvotes: 4

Peter Karabinovich
Peter Karabinovich

Reputation: 633

Because your servlet and any other filter in chain must have <async-supported>true</async-supported> in web.xml.

Upvotes: 52

user3635339
user3635339

Reputation: 31

You can use Annotation for Mapping Asynchronous Servlet like this

@WebServlet(urlPatterns = {"/yourServlet"}, **asyncSupported=true**)

public class YourServlet extends HttpServlet { }

Upvotes: 3

Yury
Yury

Reputation: 29

Peter Karabinovich, you answer isn't true. From Servlet 3.0 spec:

2.3.3.3 Asynchronous processing
...
Dispatching from a servlet that has asyncSupported=true to one where asyncSupported is set to false is allowed. In this case, the response will be committed when the service method of the servlet that does not support async is exited...

Upvotes: 1

Java_User
Java_User

Reputation: 1321

I know this an old post but I would like to share my solution. It took me 1 week to find out the cause because I had tried almost tried every possible solution.

For me the servlet url-pattern was not correct.

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

Hope it will be of some use.

Upvotes: 0

Related Questions