Search code examples
javajsongson

Using Enums while parsing JSON with GSON


This is related to a previous question that I asked here earlier

JSON parsing using Gson

I am trying to parse the same JSON, but now I have changed my classes a little bit.

{
    "lower": 20,
    "upper": 40,
    "delimiter": " ",
    "scope": ["${title}"]
}

My class now looks like:

public class TruncateElement {

   private int lower;
   private int upper;
   private String delimiter;
   private List<AttributeScope> scope;

   // getters and setters
}


public enum AttributeScope {

    TITLE("${title}"),
    DESCRIPTION("${description}"),

    private String scope;

    AttributeScope(String scope) {
        this.scope = scope;
    }

    public String getScope() {
        return this.scope;
    }
}

This code throws an exception,

com.google.gson.JsonParseException: The JsonDeserializer EnumTypeAdapter failed to deserialized json object "${title}" given the type class com.amazon.seo.attribute.template.parse.data.AttributeScope
at 

The exception is understandable, because as per the solution to my previous question, GSON is expecting the Enum objects to be actually be created as

${title}("${title}"),
${description}("${description}");

But since this is syntactically impossible, what are the recommended solutions, workarounds?


Solution

  • From the documentation for Gson:

    Gson provides default serialization and deserialization for Enums... If you would prefer to change the default representation, you can do so by registering a type adapter through GsonBuilder.registerTypeAdapter(Type, Object).

    Following is one such approach.

    import java.io.FileReader;
    import java.lang.reflect.Type;
    import java.util.List;
    
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import com.google.gson.JsonDeserializationContext;
    import com.google.gson.JsonDeserializer;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonParseException;
    
    public class GsonFoo
    {
      public static void main(String[] args) throws Exception
      {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(AttributeScope.class, new AttributeScopeDeserializer());
        Gson gson = gsonBuilder.create();
    
        TruncateElement element = gson.fromJson(new FileReader("input.json"), TruncateElement.class);
    
        System.out.println(element.lower);
        System.out.println(element.upper);
        System.out.println(element.delimiter);
        System.out.println(element.scope.get(0));
      }
    }
    
    class AttributeScopeDeserializer implements JsonDeserializer<AttributeScope>
    {
      @Override
      public AttributeScope deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
          throws JsonParseException
      {
        AttributeScope[] scopes = AttributeScope.values();
        for (AttributeScope scope : scopes)
        {
          if (scope.scope.equals(json.getAsString()))
            return scope;
        }
        return null;
      }
    }
    
    class TruncateElement
    {
      int lower;
      int upper;
      String delimiter;
      List<AttributeScope> scope;
    }
    
    enum AttributeScope
    {
      TITLE("${title}"), DESCRIPTION("${description}");
    
      String scope;
    
      AttributeScope(String scope)
      {
        this.scope = scope;
      }
    }