我正在尝试使用 Apache HttpClient(Fluent API)将数据 POST 到 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();
}
}
}
这不会打印任何输出 - detector.hasNext() 为 false。
最佳答案
要解决该问题,您需要 offer()
发送至 HttpContent
的消息的所有 block ( HttpPostRequestDecoder
)在调用getBodyHttpDatas()
之前,或者您也可以只添加 HttpObjectAggregator
处理程序就在 channel 管道的处理程序之前。如果您这样做,HttpObjectAggregator
将为您收集所有 block 并生成一个 FullHttpRequest
代替多个 block 。路过FullHttpRequest
而不是普通的HttpRequest
至HttpPostRequestDecoder
的构造函数消除了 offer()
的需要 block 。
所以你只需要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
这是聚合内容的最大长度。您可以随意传递另一个值。
关于java - 使用 Apache HttpClient 将数据发布到 netty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23989217/