我正在尝试使用 Jersey 设置 Vert.X 来处理 POST 数据(不一定是表单数据)。
Jersey ContainerRequest.setEntityStream
接受一个 InputStream
这就是我正在尝试构建的。但是,如果不使用 bodyHandler
或我自己的自定义方法(执行类似操作但限制输入)将整个数据读入内存,我似乎无法绕过传递该数据
final Buffer body = Buffer.buffer();
event
.handler(buffer -> {
if (!event.response().headWritten()) {
body.appendBuffer(buffer);
if (body.length() > 10 * 1024 * 1024) {
event.response()
.setStatusCode(REQUEST_ENTITY_TOO_LARGE.getStatusCode())
.setStatusMessage(REQUEST_ENTITY_TOO_LARGE.getReasonPhrase())
.end();
}
}
})
.endHandler(aVoid -> {
request.setEntityStream(new VertxBufferInputStream(body));
appHandler.handle(request);
});
VertxBufferInputStream
是 VertXbuffer 的简单包装器。只是为了通过避免转换为 ByteArrayInputStream() 来节省一些内存。但它有整个 body 。
我想避免使用整个正文并将其流式传输。我尝试了一些非常糟糕的代码,但最终不起作用,因为它阻塞了事件循环,因为 handler
没有被调用并且正在等待它。
最佳答案
需要两个组件。
您需要确保使用
vertx.executeBlocking
对可能阻塞的任何内容进行分离处理,请参阅https://github.com/trajano/app-ms/blob/7f1de326683473839ffe85fe711cbe719f7a0a74/ms-engine/src/main/java/net/trajano/ms/engine/JaxRsRoute.java#L128您需要处理两个事件:新的数据缓冲区进入时和结束时。 https://github.com/trajano/app-ms/blob/7f1de326683473839ffe85fe711cbe719f7a0a74/ms-engine/src/main/java/net/trajano/ms/engine/JaxRsRoute.java#L123
您需要实现一个InputStream,它能够从另一个线程接受数据,并在没有数据时阻塞,并且能够接收没有更多输入的消息。 https://github.com/trajano/app-ms/blob/master/ms-engine/src/main/java/net/trajano/ms/engine/internal/VertxBlockingInputStream.java
关于jersey - Vert.x ReadStream<Buffer> 到 InputStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46325730/