异步Servlet-首选实现 [英] Async Servlet - preferred implementation

查看:117
本文介绍了异步Servlet-首选实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,在研究Servlets中的异步处理期间,我至少遇到了三种实现方式 使用这种方法的一些功能.

Lately, during my research about asynchronous processing in Servlets, I came across at at least three ways to implement some functionality using this approach.

问题是:

  1. 哪个是最好的?
  2. 也许不建议使用其中某些方法?
  3. 也许还有比下面提到的所有方法更好的一种方法?

找到的方法:

  1. 使用AsyncContext.start(Runnable).

这种方法非常简单明了.但是许多服务器在为HTTP请求创建的线程池中执行这样的作业 (有关详细信息,请参见 http://www.nurkiewicz.com/2012/05/javaxservletservletrequeststartasync .html )

This approach is quite simple and straightforward. But many serwers executes such a job in thread pool created for HTTP requests (more about it here http://www.nurkiewicz.com/2012/05/javaxservletservletrequeststartasync.html)

使用在Servlet上下文初始化期间创建的自定义线程池

Using custom threads pool created during Servlet context initialization

(此处的示例: http://www.journaldev .com/2008/async-servlet-feature-of-servlet-3 ). 但是我可以在Servlet容器中创建自己的线程吗?在EJB中(在JavaEE7之前)不建议(甚至禁止). 我可以使用JavaSE执行器还是应该使用JavaEE7中的ManagedExecutors(假设我使用JavaEE7)?

(sample here: http://www.journaldev.com/2008/async-servlet-feature-of-servlet-3). But can I create my own threads in Servlet container? It was not recommended (or even prohibited) in EJB (before JavaEE7). Can I use JavaSE Executors or should I use ManagedExecutors from JavaEE7 (assuming that I use JavaEE7)?

使用EJB@Asynchronious批注

(此处的示例: https://github.com/wildfly/quickstart/tree/master/servlet-async/src/main/java/org/jboss/as/quickstarts/servlet/async ). 但是在这里我无法控制执行任务的线程(即应创建多少个线程等等)

(example here: https://github.com/wildfly/quickstart/tree/master/servlet-async/src/main/java/org/jboss/as/quickstarts/servlet/async). But here I have no control over threads executing my task (i.e. how many thread should by created etc.)

很高兴听到您对这个问题的想法以及您对AsyncContext的经验.

I would by glad to hear your thoughts on this issue and your experience with AsyncContext.

推荐答案

所有功能都具有相同的性能,在后端,所有线程都将请求处理线程替换为另一个线程,以便可以处理更多请求.

All will have the same performance, at the backend all threads are replacing the request processing thread to another thread, so that more requests can be served.

下面您将找到一个简单的实现:

Below you'll find a simple implementation:

@WebServlet(urlPatterns = "/AsyncLongRunningServlet", asyncSupported = true)
public class AsyncLongRunningServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Request Processing Thread "+Thread.currentThread().getName());

        request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
        response.setContentType("text/html");
        PrintWriter printWriter=response.getWriter();
        printWriter.println("<html><head><title>Asynchronous servlet</title></head><body>");
        printWriter.println("Request Processing Thread "+Thread.currentThread().getName());
        printWriter.println("<br>");
        printWriter.println("<progress id='progress' max='100')></progress>");
        printWriter.println("<br>");

        AsyncContext asyncCtx = request.startAsync();
        asyncCtx.addListener(new AppAsyncListener());
        asyncCtx.setTimeout(12000);
        //release of request processing thread
        asyncCtx.start(() ->{
            printWriter.println("<br>");
            printWriter.println("Async thread Name "+Thread.currentThread().getName());
            printWriter.println("<br>");

            int i=0;
            while(i<100)
            {
                printWriter.println("<script>document.getElementById('progress').value=\""+i+"\";</script>");
                printWriter.flush();
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                }
                i++;
            }
            printWriter.println("</body></html>");
            asyncCtx.complete();
        }

    );
        printWriter.println("<br>");
        printWriter.println("End of response");
    }

}



package com.journaldev.servlet.async;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebListener;

@WebListener
public class AppAsyncListener implements AsyncListener {

    @Override
    public void onComplete(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onComplete");
        // we can do resource cleanup activity here
    }

    @Override
    public void onError(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onError");
        //we can return error response to client
    }

    @Override
    public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onStartAsync");
        //we can log the event here
    }

    @Override
    public void onTimeout(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onTimeout");
        //we can send appropriate response to client
        ServletResponse response = asyncEvent.getAsyncContext().getResponse();
        PrintWriter out = response.getWriter();
        out.write("TimeOut Error in Processing");
    }

}

这篇关于异步Servlet-首选实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆