Wednesday, November 6, 2013

How to configure a custom gson object to Retrofit's RestAdapter

From the previous post, I decided to go with Retrofit for our sync framework for our Android app. There are few reasons behind this. Retrofit offers significantly simple syntax to let us do http GET, POST, PUT, DELETE, and HEAD operations, handles mapping of JSON to Java objects and vice versa, active community and maturer than other alternatives; the fact that Jake Wharton from Square is actively developing on this makes me feel comfortable to go with them as well.

In this post, I am trying to demonstrate how you can use Retrofit to hook up with a modern API service and configure few global mapping definitions. One thing I find in Android community is a lack of intro, how to get started type of articles. Since myself is a newbie to Android development, I would like to document as much as I can to build an Android app with using whatever tools we find the best to work with (any suggestions are welcome!).

Disclaimer: I don't know what I'm doing (yet). I started an Android development literally few weeks ago, so a code sample here is not necessarily the way it should be implemented. Just keep that in mind, and I will make improvement as I get better at it.

How to install Retrofit
We use gradle for a build tool, which works nicely once it sets up correctly.
just add
 compile 'com.squareup.retrofit:retrofit:1.2.2'  
in dependencies.

Setting up Retrofit
RestAdapter is an interface to a REST API. You want to create a singleton instance for a REST API that you want to talk to.

 sRestAdapter = new RestAdapter.Builder().setRequestInterceptor(new RequestInterceptor() {  
       @Override  
       public void intercept(RequestFacade requestFacade) {  
         requestFacade.addHeader("Authorization", "Bearer yourToken");  
       }  
     })  
         .setServer(API_URL)  
         .build();  
I want to add a header with an authentication token for every request we make. so the above line with RequestInterceptor accomplishes that. Set the server URL and you're good.

This will be enough to get you started. But I needed to add few more global wide customization to RestAdapter. I want to add a global mapping rule so that JSON keys with snake_case should be mapped to camelCase keys in Java objects and vice versa. Another customization I wanted to make is I need to correctly map date and date time values to Java objects. Bit tricky thing is that we need to handle two types of dates. One with only date and the other is with time. We can accomplish these customizations by creating our own Gson object (Gson does actual mapping).

This is how I constructed a Gson object to meet the needs above.

 Gson gson = new GsonBuilder()  
           .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)  
           .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")  
           .registerTypeAdapter(Date.class, new DateDeserializer())  
           .create();  
private static final String[] DATE_FORMATS = new String[] {  
       "yyyy-MM-dd'T'HH:mm:ssZ",  
       "yyyy-MM-dd"  
   };  
private static class DateDeserializer implements JsonDeserializer<Date> {  
  @Override  
  public Date deserialize(JsonElement jsonElement, Type typeOF,  
              JsonDeserializationContext context) throws JsonParseException {  
    for (String format : DATE_FORMATS) {  
      try {  
        return new SimpleDateFormat(format, Locale.US).parse(jsonElement.getAsString());  
      } catch (ParseException e) {  
      }  
    }  
    throw new JsonParseException("Unparseable date: \"" + jsonElement.getAsString()  
        + "\". Supported formats: " + Arrays.toString(DATE_FORMATS));  
  }  
}  
and you add this gson object to the restAdapter by
 setConverter(new GsonConverter(gson))  

There you go. Now every JSON conversion will follow the rules defined above.
Making a http GET request is slightly simple and the official documentation does fairly good job of describing steps. So I won't go over that here.


Next up is setting up a database system and store the java objects after it's been mapped. I hope to address that soon.
Happy Android coding:)

7 comments:

  1. http://stackoverflow.com/questions/27416413/how-to-customize-a-specific-date-field-in-json-using-gson-api-in-java

    ReplyDelete
  2. This is extremely helpful info!! Very good work. Everything is very interesting to learn and easy to understood. Thank you for giving information. visit essay valley to get your essay done

    ReplyDelete
  3. Nice info, I need example for Auth bearer at Retrovit 2.0.+

    ReplyDelete
  4. This is a very helpful blog entry! Thanks a lot for sharing. By visiting http://dissertationwriting.services/, you can be confident about your writing skills.

    ReplyDelete
  5. When you're tired, you want to relax after a stressful working hours, you need to have time to take care of the kids active.
    Please visit our website and play exciting flash games.
    Thanks you for sharing!
    Friv 4

    ReplyDelete
  6. I have always loved reading programming blogs and having come across this blog on Gson, I have acquired a lot of motivation to read it. The segments of codes which are indicated in this blog are simplified and useful. I will be trying this in my future programming practices. Expert Writing Service for programming assignments is now available online

    ReplyDelete