Jersey:异步请求后立即响应

Scy*_*yla 8 java rest multithreading asynchronous jersey

我试着理解异步响应与Jersey一起工作的方式.我阅读了Jersey文档的第10章(https://jersey.java.net/documentation/latest/async.html),但它对我的问题没有帮助.此处关于stackoverflow的研究也没有得到令人满意的答案(我能理解).

我要做的是类似于这篇文章中的一个问题(使用http状态202进行异步操作).我想使用HTML表单文档将大文件上传到服务器.在将请求发送到服务器之后,Web服务应立即响应状态202和URI,其中在请求完成后可以找到该文件.

阅读帖子后,似乎有可能,但遗憾的是没有提示如何在给定的情况下实现这样的行为.

我写了一个小的Web服务来测试功能:

    @Path("/test/async/")
    public class TestAsyncResponse {

        @GET
        @Path("get")
        public Response asyncGet(@Suspended final AsyncResponse response) {

            new Thread(new Runnable() {

                @Override
                public void run() {

                    DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");

                    System.out.println("#### thread started: " 
                                       + df.format(new Date()) + " ####");
                    String result = veryExpensiveOperation();
                    System.out.println("#### thread finished: " 
                                        + df.format(new Date()) + " ####");

                    response.resume(result);
                }

                private String veryExpensiveOperation() {

                    try {

                        Thread.sleep(10000);
                    } 
                    catch (InterruptedException e) {

                        e.printStackTrace();
                    }

                    return "Woke up!";
                }
            }).start();

            return Response.status(202).entity("Request accepted. " + 
                                        "Long running operation started")
                                        .build();
        }
    }
Run Code Online (Sandbox Code Playgroud)

该服务有效但作为回应我得到了"醒来!" 10秒等待后的消息而不是202响应似乎是合乎逻辑的,因为它AsyncResponse是处理响应的响应(据我所知).

在阅读完文档之后,我得到的印象是,假设这是因为所有Jersey都使用异步服务器响应将线程从响应线程池外包给另一个线程以释放处理时间以获得对服务的更多响应.

所以我的两个问题是:我的理解是否正确,我可以使用异步服务器响应来获得所需的行为吗?

我尝试启动一个没有的新线程AsyncResponse,我得到一个NullPointerException因为泽西已经关闭了响应,因此关闭了InputStream包含文件数据.这是预期的行为吗?这篇文章(/sf/answers/1229177911/)似乎表明它可能有效.

非常感谢任何回应.

问候

mik*_*jov 4

你的问题是混合两个主题。

从 HTTP 角度来看,202 从技术上讲是一个已完成的请求。请求的结果是 202,服务器告诉你它将在旁边执行。您必须发出另一个 HTTP 请求才能获取更新的状态。

从应用程序的角度来看,异步意味着您将在单独的线程(或其他异步方式)中执行请求。而且,这也意味着在另一个“veryExppressiveOperation”完成之前,您不会返回结果,甚至不会返回 202。跳过这个循环的全部目的是释放调用线程。您的 Web 服务器数量有限,例如 20 个,如果您的每个请求都花费很长时间,那么所有 20 个请求都会挂起。使用 @Suspished 您可以将执行从 Web 服务器线程转移到其他方式(您的情况下是另一个线程)。这实际上只是第一步。异步服务器背后的想法是,即使非常昂贵的操作也是以某种异步方式实现的,这样等待数据库或文件就不会占用整个线程。