Jersey Vert.x ReadStream<;缓冲区>;输入流
我试图用Jersey设置Vert.X来处理POST数据(不一定是表单数据) JerseyJersey Vert.x ReadStream<;缓冲区>;输入流,jersey,vert.x,Jersey,Vert.x,我试图用Jersey设置Vert.X来处理POST数据(不一定是表单数据) JerseyContainerRequest.setEntityStream接收一个InputStream,这正是我试图构建的。但是,如果不使用bodyHandler或我自己的自定义方法将整个内容读取到内存中,我似乎无法绕过传递数据的过程,该方法会执行类似的操作,但会限制输入 final Buffer body = Buffer.buffer(); event .handler(buffe
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()来节省一些内存。但它有整个身体
我不想让整个身体都流下来。我已经尝试了一些非常粗糙和糟糕的代码,但最终都不起作用,因为它阻止了事件循环,因为
处理程序没有被调用并且正在等待它。这是一个很好的问题需要解决:)
你可以从中得到灵感
其中,Jersey与Netty实现了集成
我相信解决了完全相同的问题(尽管对于不同的Web服务器,在本例中是Netty),即:
http请求在事件循环(由Netty)上处理,因此必须在不同的线程(非事件循环)上调用ApplicationHandler.handle()
方法
非阻塞API必须转换为阻塞InputStream
。这是在NettyInputStream
上实现的。它利用了这样一个事实,即Netty的ByteBuf
可以很容易地转换为InputStream
,因此通过使用LinkedBlockingDeque
这些InputStreams可以转换为单个InputStream。(仅供参考,我不能100%确定是否保证提供程序(事件循环线程)永远不会阻塞这将是一个bug。)
顺便说一下,这只是对传入数据的处理。对于响应,您必须实现将OutputStream
(Jersey使用)转换为Vert.X非阻塞API。需要两个组件
您需要确保使用vertx.executeBlocking
将任何可能阻塞的处理分开
您需要处理两个事件:数据的新缓冲区进入时和结束时
您需要实现一个InputStream,该InputStream能够在没有数据时从另一个线程和块接收数据,并能够接收没有更多输入的消息。
谢谢,我也调查过了。我的一次尝试与之类似,但它仍然会阻塞,因为“take()”会阻塞。我不明白。那很好take()
正在阻塞(这是InputStream.read()
的约定)。重要的部分是我在[1]中描述的,ApplicationHandler.handle()
必须委托给不同的线程。因此,另一个线程调用了take()
方法,并且一切工作正常。除非Jersey附带了非阻塞API,否则别无选择,但这并没有发生(很不幸,但很接近)。正确,这是最接近的一个。(我现在刚让它工作起来)