martes, 16 de abril de 2013

Gson and how nice it is

Tired of Jackson are you?
Do you want to serialize a POJO and not have to add all those annotations?
Just want to try a different way to deal with Json?

The I have an answer for you: Google Gson.

Gson is the Google library to deal with JSON and serialization, but in a easier way.
For starters you don't need to use annotations for the properties or the methods, it uses (out of the box) the POJO convention and introspection to serialize the class.

So for example if you just want to serialize some Java class you have you'll have to do the following:
Gson gson = new GsonBuilder().create();
gson.toJson(anObject);

And to de-serialize it you'll do:
Gson gson = new GsonBuilder().create();
gson.fromJson(aJsonString, anObject.getClass());


Now one thing I just keep forgetting how to do (hence the name of the blog) is how to deserialize a plain old collections let say a List of Strings, and here is how:
 
import java.lang.reflect.Type;
Type type = new TypeToken<List<String>>() { }.getType();
List<String> aList =  new Gson().fromJson(jsonData, type);

As you can see it is quite simple to use, and of course this is just a really really really small port of what you can do with it, but it was a nice excuse for me to post how to deserialize a collection :P.  

For more information just check the Gson site here :

https://sites.google.com/site/gson/gson-user-guide

Any way I hope you can use it.
 

Dealing with GZIP Content

So .... Long time no see eh?
Oh well there are many reasons for that but truth is "you don't care about that".
Let's jump then into this post topic, which is ZIPED content.

As you may or may not know web servers can send you the content you are requesting in a compress way. Main reason for this is, of course, cause you save bandwidth.
Problem being, you have to deal with that content.
As it turns out you usually come across this when you are creating some sort of HTTP client to consume something and when you try to print the data you can no read it (this is what happened to me).

Easiest way to know for sure that the server is doing this is, checking the following HTTP header:

Content-Encoding: gzip 

This tells you that the "content" has been "gziped", quite obvious rigtht?

Now lets talk about code, how do I deal with this.
Well if you are a smart chap and you are using Jersey Client, this is how:


import com.sun.jersey.api.client.filter.GZIPContentEncodingFilter;

List<ClientFilter> clientFilters = new ArrayList<ClientFilter>();
clientFilters.add(new GZIPContentEncodingFilter(false));


if (clientFilters != null) {
  for (ClientFilter clientFilter : clientFilters) {
      client.addFilter(clientFilter);
  }
}


As you can imagine the client is the Jersey Client, and basically what this code does is to add a filter.
For Jersey filters are plugin of code that in the end knows how to do certain stuff with the payload you send.
In this case this filter "GZIPContentEncodingFilter" knows how to add the HTTP header I showed you before BUT ALSO, it knows how to zip the payload you're seeing.

Now that I've showed you how to handle this with Jersey I've also thought it'll be a good idea to show you just how to decode and encode any content in the same way, and this is how:

Decode: 
InputStream io = (InputStream) someInputStreamYouHad;
String payload = new String(IOUtils.toByteArray(new GZIPInputStream(io)));


Encode:

OutputStream os = new ByteArrayOutputStream();
OutputStream realOs = new GZIPOutputStream(os);
      
realOs.write(payload.getBytes());

realOs.close();
payload = os.toString();


And that's it, hope it helps you/me.