I am struggling with some issue related with http, java and the stackexchange API. Consider the following URL as string:
private static final String URLSTRING_2 = "http://freegeoip.net/json/";
if I write this URL in my browser I get this answer as JSON:
now I'm trying to do that with java and only native libs, for that am using the snippet below which is working so far so good...
If I parse the JSON and I try to get the value for the key "country_name" then the snippet prints as expected "Singapore"
public static void main(String[] args) throws Exception {
// Connect to the URL using java's native library
final URL url = new URL(URLSTRING_2);
final HttpURLConnection request = (HttpURLConnection) url.openConnection();
request.connect();
// Convert to a JSON object to print data
final JsonParser jp = new JsonParser(); // from gson
final JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); // Convert the input stream to a json
// element
final JsonObject rootobj = root.getAsJsonObject(); // May be an array, may be an object.
final String country = rootobj.get("country_name").getAsString(); // just grab the zipcode
System.out.println("country_name: " + country);
}
if I do the same with this link https://api.stackexchange.com//2.2/users/22656?order=desc&sort=reputation&site=stackoverflow&filter=!T6oHjO_RIWkfWpoL5g
my browser outputs the following JSON:
but if I try to parse the JSON I get an exception because am getting from the request this:
ý•@‡ž¼ÚRìØ1ôX`»v?±h[‹-¹’/+ò........
for something that is not even human readable...
do you know why?
Thanks in advance
The StackOverflow API GZIP-compresses its response. The reason you see that string of non-human-readable characters is that you are trying to read GZIP-compressed data without first decompressing it.
Your browser is capable of reading this header and doing the decompression itself. Your code isn't yet.
You can confirm that GZIP compression is used by displaying the value of the Content-Encoding header in the response. Adding the line
System.out.println(request.getContentEncoding());
will print out
gzip
Fortunately, fixing the problem is fairly straightforward. You need to wrap the InputStream
you get from the request in a GZIPInputStream
:
final JsonElement root = jp.parse(new InputStreamReader(new GZIPInputStream((InputStream) request.getContent()))); // Convert the input stream to a json
However, instead of the built-in Java classes, I'd recommend using a library such as Apache HTTPComponents Client for making your HTTP requests. In particular, a library such as this will automatically detect the content-encoding and do the decompression for you.