Kyle Banks

Java: Integer to Enum Mapping with Google's GSON

Written by @kylewbanks on Mar 1, 2013.

A lot of times when using a REST API, it is effective to map integers from your JSON to an enum in your Java models. With Google's GSON library, the process of doing this is can be a little tricky, but I find it well worth the added effort to do so.

If you are not familiar with GSON, it is a very powerful JSON deserialization library that seamlessly transforms JSON objects (or arrays) to Java objects. The only data type I ever seem to find it lacking in is enums. The reason is fairly obvious, as enums don't exactly have an integer value, so GSON has no idea how to perform the mapping. It is also worth noting that while I will be showing an integer to enum mapping, this will also work with Strings, floats, etc.

Let's take a look at a simple enum, and how we can map it to an integer value.

public enum TicketType {
     REGULAR, VIP, ALL_ACCESS
}

This simple enum describes ticket types, and has three distinct values. Now, our REST API returns these values as integers, so we will need to give them the appropriate values based on what the API specifies.

public enum TicketType {
     REGULAR(1), VIP(2), ALL_ACCESS(3);
     
     private final int key;
     
     TicketType(int key) {
          this.key = key;
     }

     public int getKey() {
          return this.key;
     }     
}

Now each TicketType value will be instantiated with the integer key that we can use to determine their JSON value. Easy enough so far, but how do we actually map this with GSON? We need one more method on the enum to return the instance of the enum with the appropriate value.

public enum TicketType {
     REGULAR(1), VIP(2), ALL_ACCESS(3);
     
     private final int key;
     
     TicketType(int key) {
          this.key = key;
     }

     public int getKey() {
          return this.key;
     }     

     public static TicketType fromKey(int key) {
          for(TicketType type : TicketType.values()) {
               if(type.getKey() == key) {
                    return type;
               }
          }
          return null;
     }

}

This new method will return the appropriate TicketType for the key passed, or null if the key was invalid. Now we almost have enough functionality to instruct GSON on how to use this enum. Unfortunately, we need an intermediate class that can take the integer, and deserialize it into an enum.

package com.example;

import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.example.TicketType;

public class TicketTypeDeserializer implements JsonDeserializer<TicketType> {

	@Override
	public TicketType deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2) throws JsonParseException {
		int key = element.getAsInt();
		return TicketType.fromKey(key);
	}

}

This class is very simple, and essentially just makes use of the static fromKey(int key); method by reading an integer from the appropriate JSON element, and passing it along. Now we are finally ready to instruct GSON of this mapping.

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(TicketType.class, new TicketTypeDeserializer());
Gson gson = gsonBuilder.create();

You can now proceed to use GSON as usual, and it will understand how to map the appropriate integers to our TicketType enum.

Let me know if this post was helpful on Twitter @kylewbanks or down below, and follow me to keep up with future posts!