web-dev-qa-db-fra.com

Servlet 3.0 pris en charge par Async ne fonctionne pas

Voici mon 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>

Voici la classe:

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

}

Je l'exécute sur glassfish et également sur Tomcat 7, a une 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)

Qui peut m'aider à ce sujet? Merci beaucoup.

24
Ben

Parce que votre servlet et tout autre filtre de la chaîne doivent avoir <async-supported>true</async-supported> dans web.xml.

51
Peter Karabinovich

J'ai eu un problème similaire, mais dans mon cas, ce n'était pas suffisant. Si vous utilisez des balises Context et Valve (dans Tomcat7 - service.xml), vous devez ajouter le paramètre asyncSupported = "true" dans la valeur de la balise. Ensuite, cela avait fonctionné.

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

Vous appelez récursivement this.doFilter(req, res, chain);.

Si vous souhaitez continuer la chaîne, vous devez appeler chain.doFilter(httpRequest, httpResponse); au lieu de this.doFilter(req, res, chain);.

4
Juan Ignacio

Vous pouvez utiliser Annotation pour mapper un servlet asynchrone comme celui-ci

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

public class YourServlet extends HttpServlet { }
3
user3635339

Peter Karabinovich, vous répondez que ce n'est pas vrai. De la spécification Servlet 3.0:

2.3.3.3 Traitement asynchrone
...
L'envoi d'une servlet qui a asyncSupported = true à une où asyncSupported est définie sur false est autorisé. Dans ce cas, la réponse sera validée lorsque la méthode de service de la servlet qui ne prend pas en charge async est quittée ...

2
Yury

Je sais que c'est un ancien message mais je voudrais partager ma solution. Il m'a fallu une semaine pour découvrir la cause car j'avais essayé presque toutes les solutions possibles.

Pour moi, le modèle d'URL du servlet n'était pas correct.

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

J'espère que cela vous sera utile.

1
Java_User