使用CompletableFuture实现非阻塞异步的Jersey JAX-RS

5

我正在学习Jersey,书上说你可以使用CompletableFuture(和CompletitionStage)以非阻塞IO的方式调用API。

但是当我使用Postman调用API时,总是得到500的错误。

如果我调试代码,我会发现方法被正确地调用了。

第一个GET方法是同步的,可以正常工作。第二个和第三个返回错误500

我错过了什么吗?

@Path("/hello")
public class HelloController {

  @GET
  @Path("/first")
  @Produces(MediaType.TEXT_PLAIN)
  public String first() {
    return "It works";
  }

  @GET
  @Path("/second")
  @Produces(MediaType.TEXT_PLAIN)
  public CompletionStage<Response> second() {
    return CompletableFuture.supplyAsync(() -> Response.accepted().entity("Hello!").build());
  }

  @GET
  @Path("/third")
  @Produces(MediaType.TEXT_PLAIN)
  public CompletableFuture<Response> third() {
    return CompletableFuture.supplyAsync(() -> Response.accepted().entity("Hello!").build());
  }
}

2
https://jersey.github.io/documentation/latest/async.html - Paul Samsotha
请在评论中回答,以便我将您的答案分配为正确答案。谢谢。 - Alessandro Argentieri
@AlexMawashi 如果您解决了问题,可以发布您自己的答案并接受它。 - Bentaye
1
你的方法是正确的,这是 @Suspended 的一种替代方式。你只需要 1) 启动一个线程来执行逻辑并在 CompletableFuture 上调用 complete 即可。 - kolossus
1个回答

4

以下是使用Jersey创建异步端点的正确方法:

@POST
@Path("/goes")
@Consumes("application/json")
@Produces("application/json")
public void createTodoAsync3(@Suspended final AsyncResponse asyncResponse, Todo todo) {

    CompletableFuture<Response> future = CompletableFuture.supplyAsync(() -> createTodo3(todo));
    future.thenAccept(resp -> asyncResponse.resume(resp));
}
private Response createTodo3(Todo todo) {
    //all logic goes here
    return Response.accepted().entity(todo).build();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接