简体   繁体   中英

How to use Servlet 3 @WebServlet & async with Spring MVC 3?

I would like to integrate the servlet 3.0 async support with spring MVC. Something like:

@RequestMapping("/chat")
@WebServlet(name="myServlet", asyncSupported=true)
public String getMessage(String userName) {
      ......
}

is it possible?

Not so fast, it is not that easy to implement good long polling. The method you mentioned works well, but there is a serious issue of "thread starvation"

Each Long polling will use up one thread, if you have 1000 concurrent user you would need 1000 thread to service the long polling request ( which most of the time does update of the server side status on the client browser)

Jetty 6 has a continue pattern whcih cleverly releases the thread of long polling request to be used by rhe real application logic.

Not yet implemented in Spring Framework 3.x. See https://jira.springframework.org/browse/SPR-5587 and https://jira.springsource.org/browse/SPR-8517

If what you want is comet support (long-polling ajax) You "might" try CometD ( http://cometd.org/documentation/cometd-java/server/services/integration-spring ). But I warn you that I have dropped it, it's just to bloated! (Such a simple thing like long polling requires days of configuration??!)

I would just implement myself some RESTful controllers in Spring3 and program myself the long polling . Make your Ajax-style request to the server, your controller keeps it open until the server has new data to send to the browser. The browser initiates a new long polling request in order to obtain subsequent events. To avoid connection timeouts just return dummy values that make the client repeat the request.

Plain easy way is most of the time the best solutions.

The question is quite old, but still unanswered. The author wanted async support in Spring MVC, and the solution is still not given.

As previous answer stated, async support request was submitted to spring community bugtracker, and was to be implemented in Spring 3.1.0. This got released recently, but according to release notes "Servlet 3.0 support" is planned to be made in version 3.2.0: https://jira.springsource.org/browse/SEC-1685

I need highly efficient COMET for my application. My current implementation is based on this example: http://code.google.com/p/jquery-stream/wiki/EchoExample , but I'm interested in moving it to Spring MVC controller. As for now, I've just improved the example and manually injected there spring beans to allow communication with the rest of the application. I had some problems with it, described in my question: Tomcat 7 Async Processing failing - only one request processed simultanously . As for now it is working fine.

I've found example which uses jboss solutions: http://docs.jboss.org/resteasy/docs/1.0.0.GA/userguide/html/Asynchronous_HTTP_Request_Processing.html , but using jboss as for me is no solution. JBoss is too big, too slow and too hard to develop on.

You can sort of do this now with the fantastic Atmosphere library:

Here is a Spring MVC example: https://github.com/ghillert/atmosphere-spring-web-mvc

Yes, you can use now. You've to add ApplicationInitializer class which extends the AbstractAnnotationConfigDispatcherServletInitializer class.

package co.tellmehow.config
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
    protected Class<?>[] getRootConfigClasses () {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses () {
        return new Class<?>[]{ApplicationWebConfig.class};
    }
    @Override
    protected String[] getServletMappings () {
        return new String[]{"/"};
    }
}

We've to extend AbstractAnnotationConfigDispatcherServletInitializer class which is used when an application context hierarchy is not required, applications may return all configuration via getRootConfigClasses() and return null from getServletConfigClasses() .

Now you can use @WebServlet annotation with your Spring Application.

Full source code with explanation present here.

@WebServlet(name = "myServlet", urlPatterns = "/myServlet")
public class MyServlet extends HttpServlet {


    private static final long serialVersionUID = 7088410241741084414L;

    @Override
    protected void doGet (HttpServletRequest req,
                          HttpServletResponse resp)
              throws ServletException, IOException {

        System.out.println("-- In MyServlet --");
        PrintWriter writer = resp.getWriter();
        writer.println("Tell Me How: MyServlet running now");
    }
}

Servlet 3.0 async support is currently being considered. If you have specific scenarios you'd like to see reflected, please comment under SPR-8517 or watch the ticket and follow the discussion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM