Decoding the gziped response in HttpClient

I am using Apache Http Client to get Http response from a a web site and display that response in the portlet. That website supports GZIP and i wanted to take advantage of it. So i built this sample code to demonstrate how you can set Accept-Encoding header while making Http call to the web site and then once you get response check if the response is gziped using value of Content-Encoding header and if yes decode that value


package com.webspherenotes.performance;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.util.zip.GZIPInputStream;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;

public class GZIPHttpClient {

public static void main(String[] args) {
HttpClient client = new HttpClient();

HttpMethod method = new GetMethod("http://www.apache.org");
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
System.out.println("Setting gzip header explicitiy");
method.addRequestHeader("Accept-Encoding", "gzip");
try {
int statusCode = client.executeMethod(method);

if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
Header[] responseHeader = method.getResponseHeaders();
for(int i = 0 ; i < responseHeader.length ;i++){
Header header = responseHeader[i];
System.out.println(header.getName() +" " + header.getValue());
}
String responseBody = getResponseBody(method);
System.out.println(new String(responseBody));

} catch (HttpException e) {
System.err.println("Fatal protocol violation: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
} finally {
// Release the connection.
method.releaseConnection();
}
}

public static String getResponseBody(HttpMethod method) throws IOException{
Header contentEncoding = method.getResponseHeader("Content-Encoding");
System.out.println("Value of Content-encoding header " + contentEncoding);
if(contentEncoding != null ){
String acceptEncodingValue = contentEncoding.getValue();
if(acceptEncodingValue.indexOf("gzip") != -1){
System.out.println("This is gzipped content " );
StringWriter responseBody = new StringWriter();
PrintWriter responseWriter = new PrintWriter(responseBody);
GZIPInputStream zippedInputStream = new GZIPInputStream(method.getResponseBodyAsStream());
BufferedReader r = new BufferedReader(new InputStreamReader(zippedInputStream));
String line = null;
while( (line =r.readLine()) != null){
responseWriter.println(line);
}
return responseBody.toString();
}
}
System.out.println("The response is not zipped");
return method.getResponseBodyAsString();
}
}


You can let a Http Server know that you can handle gzip response by setting Accept-Encoding header like this method.addRequestHeader("Accept-Encoding", "gzip").

If the HttpServer is able to compress the response using gzip it will do that and set Content-Encoding header with value equal to gzip. In your client code you will have to check if this header is set if yes, unzip the response body

No comments: