16

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.

Alex Bliskovsky
  • 5,325
  • 7
  • 28
  • 40
  • Can you be more specific please? What exactly is "a gzipped string"? A gzipped request parameter? Or a gzipped request body? Does your server support gzipped requests? (not all do...) The HttpClient transparent GZIP support which you're reading about concerns HTTP responses, not HTTP requests. – BalusC Aug 22 '11 at 20:56
  • Oh, HTTPLib and HttpClient are different libraries... – BalusC Aug 22 '11 at 20:58
  • I've edited my question. I meant HttpClient and a gzipped request parameter. Thanks. – Alex Bliskovsky Aug 22 '11 at 21:13
  • Just a single gzipped parameter, not the entire request body? How would you send it? As a Base64-encoded parameter value or as a `multipart/form-data` part? 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? – BalusC Aug 22 '11 at 21:16
  • This would be as part of a `multipart/form-data` request. The server expects a gzipped parameter. – Alex Bliskovsky Aug 22 '11 at 21:19
  • OK, what's the original type of this part value? A `String`? A `File`? Etc. – BalusC Aug 22 '11 at 21:28

1 Answers1

19

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"));
BalusC
  • 1,040,783
  • 362
  • 3,548
  • 3,513
  • Is this also possible when using a WebView? – RvdK Oct 16 '12 at 11:20
  • 1
    If you were to assume the data `POST`ed 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. – HGPB Mar 14 '13 at 15:42
  • 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. – djechlin Jan 14 '14 at 19:45
  • @HGPB You would need chunked request with multipart enabled. This will avoid throwing out of memory. – Arun George Mar 23 '17 at 08:55