首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReadStream<Buffer>到InputStream

ReadStream<Buffer>到InputStream
EN

Stack Overflow用户
提问于 2017-09-20 15:10:09
回答 2查看 2.9K关注 0票数 1

我正在尝试在泽西岛设置Vert.X来处理POST数据(不一定是表单数据)。

泽西岛的ContainerRequest.setEntityStream采用了一个InputStream,这正是我想要构建的。但是,如果不使用bodyHandler或我自己的自定义方法将整个数据读入内存,我似乎无法绕过传递数据的问题,这种方法可以执行类似的操作,但限制输入。

代码语言:javascript
复制
    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()。但它拥有整个身体。

我想避免拥有整个身体,让它流动。我尝试过一些东西,它们都是非常讨厌和糟糕的代码,它们最终无法工作,因为它阻止了事件循环,因为handler没有被调用,并且正在等待它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-20 21:17:29

有两个组件是必需的。

  1. 您需要确保将任何可能使用vertx.executeBlocking阻止的处理分离(请参阅https://github.com/trajano/app-ms/blob/7f1de326683473839ffe85fe711cbe719f7a0a74/ms-engine/src/main/java/net/trajano/ms/engine/JaxRsRoute.java#L128 )。
  2. 您需要处理两个事件:数据的新缓冲区何时进入,何时结束。https://github.com/trajano/app-ms/blob/7f1de326683473839ffe85fe711cbe719f7a0a74/ms-engine/src/main/java/net/trajano/ms/engine/JaxRsRoute.java#L123
  3. 您需要实现一个InputStream,它能够在没有数据的情况下接受来自另一个线程和块的数据,以及接收没有更多输入的消息的能力。https://github.com/trajano/app-ms/blob/master/ms-engine/src/main/java/net/trajano/ms/engine/internal/VertxBlockingInputStream.java
票数 1
EN

Stack Overflow用户

发布于 2017-09-20 20:35:04

如此美丽的问题需要解决:)

您可以在https://github.com/jersey/jersey/blob/12e5d8bdf22bcd2676a1032ed69473cf2bbc48c7/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyHttp2ServerHandler.java#L124获得灵感,在那里可以实现泽西与Netty的集成。

我认为解决的问题完全相同(虽然对于不同的for服务器,本例中的Netty ),即:

  1. http请求是在事件循环(由Netty处理)上处理的,因此必须在另一个线程(非事件循环)上调用ApplicationHandler.handle()方法。
  2. 非阻塞API必须转换为阻塞InputStream。这是在NettyInputStream实现的。它利用了这样一个事实,即Netty的ByteBuf可以很容易地转换为InputStream,因此通过使用LinkedBlockingDeque,可以将这些InputStreams转换为单个InputStreams。(只是fyi,我不能100%确定提供者(事件循环线程)是否被保护为永不阻塞,这将是一个错误。)

顺便说一句,这只是对传入数据的处理。对于响应,您必须实现OutputStream (由泽西岛使用)到Vert.X非阻塞API的转换。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46325730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档