I need to send a POST request to a web server which includes a gzipped request parameter. I'm using Apache HttpClient and I've read that it supports Gzip out of the box, but I can't find any examples of how to do what I need. I'd appreciate it if anyone could post some examples of this.
2 Answers
You need to turn that String into a gzipped byte[] or (temp) File first. Let's assume that it's not an extraordinary large String value so that a byte[] is safe enough for the available JVM memory:
String foo = "value";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (GZIPOutputStream gzos = new GZIPOutputStream(baos)) {
gzos.write(foo.getBytes("UTF-8"));
}
byte[] fooGzippedBytes = baos.toByteArray();
Then, you can send it as a multipart body using HttpClient as follows:
MultipartEntity entity = new MultipartEntity();
entity.addPart("foo", new InputStreamBody(new ByteArrayInputStream(fooGzippedBytes), "foo.txt"));
HttpPost post = new HttpPost("http://example.com/some");
post.setEntity(entity);
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(post);
// ...
Note that HttpClient 4.1 supports the new ByteArrayBody which can be used as follows:
entity.addPart("foo", new ByteArrayBody(fooGzippedBytes, "foo.txt"));
4 Comments
RvdK
Is this also possible when using a WebView?
HGPB
If you were to assume the data
POSTed had the potent of being huge, how could it be done using HTTPClient? I am currently having out of memory issues on low VM heap (16MB) devices.djechlin
This is a good answer, but I'm still going to complain about how a one-line operation takes 20 lines of code using the most standard Java library.
Arun George
@HGPB You would need chunked request with multipart enabled. This will avoid throwing out of memory.
Try the GzipCompressingEntity class. If I'm zipping the body of a post e.g. for a JSON object I would go:
// json payload
if (jsonBody != null) {
post.setHeader("Content-Type", "application/json");
StringEntity requestEntity = new StringEntity( jsonBody, ContentType.APPLICATION_JSON);
if (gzipBody) {
GzipCompressingEntity gzippedEntity = new GzipCompressingEntity(requestEntity);
post.setEntity(gzippedEntity);
}else {
post.setEntity(requestEntity);
}
}
Haven't tested but I assume for adding parameters you'd do:
// add parameters
if (parameters != null && parameters.length > 0){
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
for (int i = 0; i < parameters.length; i++){
urlParameters.add(new BasicNameValuePair(parameters[i][0], parameters[i][1]));
}
post.setEntity(new GzipCompressingEntity(new UrlEncodedFormEntity(urlParameters)));
}
multipart/form-datapart? Are you sure that the target server can handle this? What exactly is the server expecting? Or is the server code under your full control as well?multipart/form-datarequest. The server expects a gzipped parameter.