-
-
Save premnirmal/8526542 to your computer and use it in GitHub Desktop.
import com.android.volley.NetworkResponse; | |
import com.android.volley.ParseError; | |
import com.android.volley.Response; | |
import com.android.volley.toolbox.HttpHeaderParser; | |
import com.android.volley.toolbox.StringRequest; | |
import java.io.BufferedReader; | |
import java.io.ByteArrayInputStream; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.util.zip.GZIPInputStream; | |
public class GZipRequest extends StringRequest { | |
public GZipRequest(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener) { | |
super(method, url, listener, errorListener); | |
} | |
public GZipRequest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener) { | |
super(url, listener, errorListener); | |
} | |
// parse the gzip response using a GZIPInputStream | |
@Override | |
protected Response<String> parseNetworkResponse(NetworkResponse response) { | |
String output = ""; // note: better to use StringBuilder | |
try { | |
final GZIPInputStream gStream = new GZIPInputStream(new ByteArrayInputStream(response.data)); | |
final InputStreamReader reader = new InputStreamReader(gStream); | |
final BufferedReader in = new BufferedReader(reader); | |
String read; | |
while ((read = in.readLine()) != null) { | |
output += read; | |
} | |
reader.close(); | |
in.close(); | |
gStream.close(); | |
} catch (IOException e) { | |
return Response.error(new ParseError()); | |
} | |
return Response.success(output, HttpHeaderParser.parseCacheHeaders(response)); | |
} | |
} |
I am having problem with GZIP in volley I comment my problem here: http://stackoverflow.com/questions/25960815/accept-encoding-in-volley-doesnt-response-with-content-encoding know you what is happen?
Hi guys, that code is a quite slow because it does not use StringBuilder and the size of the BufferedReader is the default one, which is 8192 bytes.
StringBuilder output = new StringBuilder();
try
{
GZIPInputStream gStream = new GZIPInputStream( new ByteArrayInputStream( response.data ) );
InputStreamReader reader = new InputStreamReader( gStream );
BufferedReader in = new BufferedReader( reader, 16384 );
String read;
while ( ( read = in.readLine() ) != null )
{
output.append( read ).append( "\n" );
}
reader.close();
in.close();
gStream.close();
}
catch ( IOException e )
{
return Response.error( new ParseError() );
}
return Response.success(output.toString(), HttpHeaderParser.parseCacheHeaders(response));
Gzip worked out of the box for me using Volley, the secret is to not set the "Accept-Encoding gzip" header manually, since it is already set by HttpUrlConnection
. If that header is set manually then the unzipping fails for whatever reason. You can verify this by using Charles Proxy or Fiddler and seeing the request headers.
hi FrancoSabadini, you mean you don't need to unzip manually? thanks.
FrancoSabadini is absolutely right. "Accept-Encoding gzip" is already set using Volley.
If is already set, how do you send/receive zipped requests/responses? How does the server know that I'm doing explicitly a GZIP request, so it have to send me a gzipped response? I'm trying to use this code, that seems quite good, but I always get a server error when I do a GET or a POST. For the POST, I'm overriding the getBody() method and converting the JSON params into a String and then into a byte array. Is this a good approach?
No, volley not set "Accept-Encoding" manually! Do that:
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.putAll(super.getHeaders());
params.put("Accept-Encoding", "gzip,deflate");
return params;
}
to decompress, the best bet is proverbface' answer:
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
StringBuilder output = new StringBuilder();
try {
GZIPInputStream gStream = new GZIPInputStream(new ByteArrayInputStream(response.data));
InputStreamReader reader = new InputStreamReader(gStream);
BufferedReader in = new BufferedReader(reader, 16384);
String read;
while ((read = in.readLine()) != null) {
output.append(read).append("\n");
}
reader.close();
in.close();
gStream.close();
} catch (IOException e) {
return Response.error(new ParseError());
}
return Response.success(output.toString(), HttpHeaderParser.parseCacheHeaders(response));
}
I have new working code set
import com.android.volley.NetworkResponse;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.StringRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.InflaterInputStream;
/**
-
Created by Amol on 03-08-2016.
*/
public class GZipRequest extends StringRequest {public GZipRequest(int method, String url, Response.Listener listener, Response.ErrorListener errorListener) {
super(method, url, listener, errorListener);
}public GZipRequest(String url, Response.Listener listener, Response.ErrorListener errorListener) {
super(url, listener, errorListener);
}@OverRide
protected Response parseNetworkResponse(NetworkResponse response) {
return Response.success(unzipString(response.data), HttpHeaderParser.parseCacheHeaders(response));
}public static String unzipString(byte[] zbytes) {
String charsetName = "ISO-8859-1";
String unzipped = null;
try {
// Add extra byte to array when Inflater is set to true
byte[] input = new byte[zbytes.length + 1];
System.arraycopy(zbytes, 0, input, 0, zbytes.length);
input[zbytes.length] = 0;
ByteArrayInputStream bin = new ByteArrayInputStream(input);
InflaterInputStream in = new InflaterInputStream(bin);
ByteArrayOutputStream bout = new ByteArrayOutputStream(512);
int b;
while ((b = in.read()) != -1) {
bout.write(b);
}
bout.close();
unzipped = bout.toString(charsetName);
} catch (IOException e) {
e.printStackTrace();
}
return unzipped;
}
}
Dear @scottagarman,
I added something like this:
String encoding = response.headers.get("Content-Encoding"); if(encoding != null && encoding.equals("gzip")) {
I'm not sure if there is a better way to do this check somewhere else but my servers don't always gzip things.
Just my two cents, you could write also if("gzip".equals(response.headers.get("Content-Encoding"))) {
Saves you both the check on null
and the additional String
object.
BTW: you can find my implementation for a JsonArrayRequest
here: GZipJsonArrayRequest.java
I added something like this:
I'm not sure if there is a better way to do this check somewhere else but my servers don't always gzip things.