Netty 4中从ByteBuf构造HTTP Chunks及Netty 3代码迁移问题
Netty 3 HTTP分块解码迁移Netty 4方案
核心概念纠正
你对HttpChunkedInput的使用场景存在误解,该类是出站场景下发送HTTP分块内容时使用的工具类,和入站解码读取分块的需求完全无关,不需要用这个类来实现你的需求。
入站HTTP分块解码的正确实现
Netty 4已经内置了成熟的HTTP解码器,不需要你继承ReplayingDecoder自己实现分块解析逻辑,只需要按如下步骤配置Pipeline即可:
- 服务端接收客户端请求,添加
HttpRequestDecoder到Pipeline;客户端接收服务端响应,添加HttpResponseDecoder到Pipeline - 解码器会自动把入站数据拆分为三类对象传递到后续Handler:
- 第一个对象是
HttpRequest/HttpResponse实例,包含HTTP的行和头信息 - 后续依次传递多个
HttpContent实例,每个实例对应一个HTTP分块的内容,等价于Netty 3里的HttpChunk - 最后传递
LastHttpContent实例,标记整个HTTP消息的所有分块接收完成
- 第一个对象是
代码示例
// Pipeline配置 pipeline.addLast("httpDecoder", new HttpRequestDecoder()); pipeline.addLast("chunkHandler", new SimpleChannelInboundHandler<HttpObject>() { @Override protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) { if (msg instanceof HttpContent) { HttpContent chunk = (HttpContent) msg; // 直接获取分块的ByteBuf内容,对应你原Netty 3代码里的buffer.readBytes(toRead)结果 ByteBuf chunkData = chunk.content(); // 这里写你的分块处理逻辑 } if (msg instanceof LastHttpContent) { // 所有分块处理完成的收尾逻辑 } } });
ByteBuf转InputStream的API补充
如果你有其他场景确实需要把ByteBuf转为InputStream,Netty提供了ByteBufInputStream工具类,比你直接调用buffer.array()更安全(堆外内存的ByteBuf调用array()会抛出异常),用法如下:
InputStream inputStream = new ByteBufInputStream(yourByteBuf);
关于EmbeddedChannel的疑问
EmbeddedChannel是专门用于单元测试Handler逻辑的工具类,正常业务运行的场景下完全不需要使用,更不需要把线上运行的普通Channel强转为EmbeddedChannel,也不需要调整原有Channel的类型。只有你编写单元测试验证解码逻辑正确性的时候,才会用到它的readInbound()/readOutbound()方法。
内容的提问来源于stack exchange,提问作者patrickjp93
相关产品推荐
相关产品推荐

