I'm trying to use Apache HttpClient (the fluent API) to POST data to a netty server.
I've tried a few variations, I'll put two here:
1.
Client:
Request.Post(uri).bodyString("content value", ContentType.TEXT_PLAIN).useExpectContinue().execute().returnContent().asString();
Server:
final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), req);
System.out.println(decoder.getBodyHttpDatas().size());
Calling getBodyHttpDatas() throws a:
io.netty.handler.codec.http.multipart.HttpPostRequestDecoder$NotEnoughDataDecoderException
2.
Client:
Request.Post(uri).bodyForm(new BasicNameValuePair("value", "content value")).useExpectContinue().execute().returnContent().asString();
Server:
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();
}
}
}
This doesn't print any output - decoder.hasNext() is false.
To solve the problem you either need to
offer()
all chunks (HttpContent
) of a message toHttpPostRequestDecoder
before callinggetBodyHttpDatas()
, or alternatively you can just add theHttpObjectAggregator
handler right before your handler to the channel's pipeline. If you do so,HttpObjectAggregator
will collect all chunks for you and produce a singleFullHttpRequest
in place of multiple chunks. PassingFullHttpRequest
instead of an ordinaryHttpRequest
toHttpPostRequestDecoder
's constructor eliminates need tooffer()
chunks.So you just need to
pipeline.addLast(new HttpObjectAggregator(1048576))
before adding your handler. For example:1048576
here is the maximum length of the aggregated content. You are free to pass another value.