我正在尝试使用Apache HttpClient(流利的API)将数据发布到Netty服务器。

我已经尝试了几种变体,在这里我将放两个:

1。

客户:

Request.Post(uri).bodyString("content value", ContentType.TEXT_PLAIN).useExpectContinue().execute().returnContent().asString();


服务器:

final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), req);
System.out.println(decoder.getBodyHttpDatas().size());


调用getBodyHttpDatas()会引发:

io.netty.handler.codec.http.multipart.HttpPostRequestDecoder$NotEnoughDataDecoderException


2。

客户:

Request.Post(uri).bodyForm(new BasicNameValuePair("value", "content value")).useExpectContinue().execute().returnContent().asString();


服务器:

final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), req);
final InterfaceHttpData data1 = decoder.getBodyHttpData("value");

while (decoder.hasNext()) {
    final InterfaceHttpData data = decoder.next();
    if (data != null) {
        try {
            Attribute attribute = (Attribute) data;
            System.out.println(attribute.getValue());
        } finally {
            data.release();
        }
    }
}


这不会输出任何输出-解码器.hasNext()为假。

最佳答案

要解决该问题,您要么需要在调用offer()之前将消息的所有块(HttpContent)都HttpPostRequestDecodergetBodyHttpDatas(),要么可以将处理程序添加到通道的管道之前,直接将HttpObjectAggregator处理程序添加到通道中。如果这样做,HttpObjectAggregator将为您收集所有块,并生成单个FullHttpRequest代替多个块。将FullHttpRequest而不是普通的HttpRequest传递给HttpPostRequestDecoder的构造函数,从而无需offer()块。

因此,您只需在添加处理程序之前先pipeline.addLast(new HttpObjectAggregator(1048576))。例如:

public class YourServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new HttpServerCodec());
        pipeline.addLast(new HttpObjectAggregator(1048576));
        pipeline.addLast(new YourServerHandler());
    }
}


1048576这是汇总内容的最大长度。您可以自由传递另一个值。

07-24 09:20