【问题标题】:Asynchronous property in Servlet 3.0 testing queryServlet 3.0 测试查询中的异步属性
【发布时间】:2015-03-12 09:40:29
【问题描述】:

我已经使用下面的教程在 Servlet 3.0 中实现了异步属性。

http://hmkcode.com/java-servlet-3-0-asynchronous-support/

在后端实现一个可运行类后,我观察到创建了 2 个线程,其中一个以异步方式结束,另一个进行后端处理。我能够成功实现提到的异步属性。 在可运行类中,我保持了 25 秒的睡眠,我尝试在 servlet 类中使用 outStream.println(Calendar.getInstance().getTimeInMillis()),我观察到了偏差。打印的时间值println 是请求开始但 25 秒后在 URL 命中页面上打印 outStream 的时间。 我只是想了解何时在 servlet 中构建打印(基于我进行此分析的时间戳),为什么它会在工人类睡眠时间后打印在 servlet URL 命中页面中。

 @WebServlet(name="asyncServlet",value = {"/async"},asyncSupported = true)       
public class AsyncServlet extends HttpServlet 
{
private static final long serialVersionUID = 1L;
@Override
protected void handleRequest(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {
servletoutputstream out = response.getoutputstream(); 
   final AsyncContext ctx = req.startAsync();
 ctx.addListener(new AsyncListener() {
        @Override
        public void onTimeout(AsyncEvent arg0) throws IOException {
            System.out.println("onTimeout...");             
        }

        @Override
        public void onStartAsync(AsyncEvent arg0) throws IOException {
            System.out.println("onStartAsync...");              
        }

        @Override
        public void onError(AsyncEvent arg0) throws IOException {
            System.out.println("onError...");           
        }

        @Override
        public void onComplete(AsyncEvent arg0) throws IOException {
            System.out.println("onComplete...");
        }
   });
   ctx.start(new Runnable() {
        @Override
        public void run() {
             try {
        Thread.currentThread.sleep(1000);

            } catch InterruptedException e) {
                e.printStackTrace();
            }

         ctx.complete();
        }
   });
    out.write("Got the request"+calendar.getinstance().gettimeinmillis());
out.close();
}
}

这里我打印出来,输出字符串中捕获的时间是在睡眠时间之前,但它是在睡眠时间之后打印的。

我已尝试使用 PrintWriter,但仍观察到相同的输出。 有没有办法在睡眠时间之前使用上面的代码打印响应。

【问题讨论】:

  • 你能发布你的代码吗?
  • 伙计们......请有人帮忙,我无法使用上述代码以异步方式将响应发送回服务器。座右铭是异步发送响应。

标签: java multithreading jsp servlets asynchronous


【解决方案1】:

以下是您想要的代码。

     @WebServlet(name = "asyncServlet", value = { "/async" }, asyncSupported = true)
public class AsyncServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");
    final   PrintWriter out = response.getWriter(); 

        final AsyncContext ctx = req.startAsync();
        ctx.addListener(new AsyncListener() {
            @Override
            public void onTimeout(AsyncEvent arg0) throws IOException {
                System.out.println("onTimeout...");             
            }

            @Override
            public void onStartAsync(AsyncEvent arg0) throws IOException {
                System.out.println("onStartAsync...");              
            }

            @Override
            public void onError(AsyncEvent arg0) throws IOException {
                System.out.println("onError...");           
            }

            @Override
            public void onComplete(AsyncEvent arg0) throws IOException {
                System.out.println("onComplete...");
                out.close();
            }
        });
        ctx.start(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                }catch(InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    out.print("<br> Got the request : "+Calendar.getInstance().getTimeInMillis()+" For Async thread :"+Thread.currentThread().getName());
                    out.flush();

                } catch (Exception e) {
                    e.printStackTrace();
                }
                ctx.complete();
            }
        });
        try {
            long time=Calendar.getInstance().getTimeInMillis();
            out.print("<br>Got the request :"+time+" For Original thread completed :"+Thread.currentThread().getName());
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

输出:

Got the request :1426238802101 For Original thread completed :http-bio-8080-exec-14

3 秒后:

 Got the request : 1426238805101 For Async thread :http-bio-8080-exec-9

Click here查看包含异步Servlet详细代码的演示项目。

【讨论】:

  • 我看到发布第一个打印后,servlet页面仍然处于加载状态,直到3秒睡眠完成。我们可以做任何事情,即使加载状态也改变了?
  • Servlet 将处于加载状态,因为数据来自服务器异步,即使第一个请求已经完成。通常我们使用 ajax 技术来使用异步行为。使用 Firebug,你就能很好地理解行为。
  • 哦,虽然它是异步处理的,但我们无法异步获取响应。我相信我们应该将此 API 仅用于后端异步处理,而不是用于以异步方式发送响应。有什么 API 可以两者兼得吗?
猜你喜欢
  • 2011-06-15
  • 2017-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
相关资源
最近更新 更多