Quarkus中的Vertx Web路由和Reactive Pg Client问题

时间:2020-06-08 10:55:59

标签: vert.x reactive quarkus

该应用程序基于以下堆栈:

  • Quarkus 1.5.0
  • 扩展名:vertx-web,reactive-pgclient

完整代码为here

我由@Observes Router创建了一个路由器。

@ApplicationScoped
public class RoutesObserver {

    @Inject PostsHandlers handlers;

    public void route(@Observes Router router) {
        router.get("/posts").produces("application/json").handler(handlers::getAll);
        router.post("/posts").consumes("application/json").handler(handlers::save);
        router.get("/posts/:id").produces("application/json").handler(handlers::get);
        router.put("/posts/:id").consumes("application/json").handler(handlers::update);
        router.delete("/posts/:id").handler(handlers::delete);

        router.get("/hello").handler(rc -> rc.response().end("Hello from my route"));
    }

}

并将处理程序提取到独立的bean中。

@ApplicationScoped
class PostsHandlers {
    private static final Logger LOGGER = Logger.getLogger(PostsHandlers.class.getSimpleName());

    PostRepository posts;

    ObjectMapper objectMapper;

    @Inject
    public PostsHandlers(PostRepository posts, ObjectMapper objectMapper) {
        this.posts = posts;
        this.objectMapper = objectMapper;
    }

    public void getAll(RoutingContext rc) {
        this.posts.findAll().thenAccept(
                data -> rc.response()
                        .write(toJson(data))
                        .end()

        );
    }
   //... other methods.

}

PostRepository使用了Java 8 CompletionStage API。

@ApplicationScoped
public class PostRepository {
    private static final Logger LOGGER = LoggerFactory.getLogger(PostRepository.class);

    private final PgPool client;

    @Inject
    public PostRepository(PgPool _client) {
        this.client = _client;
    }

    public CompletionStage<List<Post>> findAll() {
        return client.query("SELECT * FROM posts ORDER BY id ASC")
                .execute()
                .thenApply(rs -> StreamSupport.stream(rs.spliterator(), false)
                        .map(this::from)
                        .collect(Collectors.toList())
                );
    }

当我运行此应用程序并尝试访问/posts时。它被冻结,没有响应打印。

1 个答案:

答案 0 :(得分:1)

使用write方法时,您需要(预先)设置content-length标头。

有几种方法可以解决这个问题:

  1. 您可以使用.end(toJson(data))代替write(...).end()-它会自动计算长度
  2. 您可以使用.putHeader("transfer-encoding", "chunked"),然后使用write(...).end()-如果您打算检索多个结果,这很有趣,因为它将一个块一个一个地写入客户端,避免了一次发送大量有效负载< / li>
  3. 您可以将content-length设置为:
String result = toJson(data);
rc.response()
   .putHeader("content-length", Long.toString(result.length()))
   .write(result)
   .end();