首页 > 解决方案 > 具有 CompletableFuture 的非阻塞异步 Jersey JAX-RS

问题描述

我正在学习 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());
  }
}

标签: javaasynchronousjerseyjax-rscompletable-future

解决方案


这是使用 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();
}

推荐阅读