该应用程序基于以下堆栈:
完整代码为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
时。它被冻结,没有响应打印。
答案 0 :(得分:1)
使用write
方法时,您需要(预先)设置content-length
标头。
有几种方法可以解决这个问题:
.end(toJson(data))
代替write(...).end()
-它会自动计算长度.putHeader("transfer-encoding", "chunked")
,然后使用write(...).end()
-如果您打算检索多个结果,这很有趣,因为它将一个块一个一个地写入客户端,避免了一次发送大量有效负载< / li>
content-length
设置为:String result = toJson(data);
rc.response()
.putHeader("content-length", Long.toString(result.length()))
.write(result)
.end();