StackCoder
StackCoder

Reputation: 81

GSON: Custom serializer for a specific property

Lets say I have three public properties in my JAVA class:

public int Rating = 0;
public int Scalability = 0;
public int Overview = 0;

Now, I want to JSONify objects of this class using gson. But while doing this, I want to "transform" value of Overview property. I want to run its integer value against an array of strings and load corresponding string. Then I would want JSON generated to be like: {"Rating":"1", "Scalability":"2", "Overview": "Text details from array"}

I understand that I'll need to write a custom serializer for int. But how to make sure that it runs only against Overview property?

Upvotes: 1

Views: 1416

Answers (1)

mtrovo
mtrovo

Reputation: 879

In order for it to work you have to change overview type to an Enum and create and register a TypeAdapter for this new Enum on GsonBuilder creation process.

So for your example you would have a class like this:

enum OverviewType {
    TYPE_0("Text details from array");
    public final String desc;

    private OverviewType(String desc) {
        this.desc = desc;
    }
}

class Example {
    public int Rating = 0;
    public int Scalability = 0;
    public OverviewType Overview = OverviewType.TYPE_0;

    public Example(int rating, int scalability, OverviewType overview) {
        super();
        Rating = rating;
        Scalability = scalability;
        Overview = overview;
    }

    public String toString() {
        return "Example [Rating=" + Rating + ", Scalability=" + Scalability
                + ", Overview=" + Overview + "]";
    }

}

This type adapter for the OverviewType:

class OverviewTypeAdapter extends TypeAdapter<OverviewType> {

    public void write(JsonWriter out, OverviewType value) throws IOException {
         if (value == null) {
              out.nullValue();
              return;
         }
         out.value(value.desc);
    }

    public OverviewType read(JsonReader in) throws IOException {
        String val = in.nextString();
        if(null == val) return null;

        for(OverviewType t : OverviewType.values()){
            if(t.desc.equals(val)) return t;
        }

        throw new IllegalArgumentException("Not a valid enum value");
    }

}

And registering a TypeAdapter on GsonBuilder like this:

    Gson gson = new GsonBuilder()
            .registerTypeAdapter(OverviewType.class, new OverviewTypeAdapter())
            .create();

The final usage would be something like this:

public void testGson2() {
    Gson gson = new GsonBuilder()
            .registerTypeAdapter(OverviewType.class, new OverviewTypeAdapter())
            .create();

    // serializing
    String json = gson.toJson(new Example(1, 10, OverviewType.TYPE_0));
    System.out.println(json);

    // and deserializing
    String input = "{\"Rating\":5,\"Scalability\":20,\"Overview\":\"Text details from array\"}";
    Example example = gson.fromJson(input, Example.class);
    System.out.println(example);

}

Upvotes: 1

Related Questions