Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gson custom deserializer just on field

Tags:

android

gson

I use Volley with Gson. I have a person object, I'd like to set gender, not a string, but an enum. So I'd like to write a custom deserializer for just this field, and let Gson to do the rest. How can I do that?

like image 438
user3057944 Avatar asked Oct 25 '16 09:10

user3057944


People also ask

How to use jsonserializer with Gson?

The JsonSerializer interface looks like this: After creating custom serializer for Json, we will also need to register this serializer through GsonBuilder.registerTypeAdapter (Type, Object). Gson invokes it’s call-back method serialize () during serialization when it encounters a field of the specified type.

How to honor type information during JSON deserialization?

We honor that type information during JSON deserialization. For this, we need to write our own custom serializer and deserializer. Firstly, we'll introduce a new String field called type in the base class Animal. It stores the simple name of the class to which it belongs.

How do I add a type to a JSON serialization?

Using Custom Deserializer One way to solve this is to add type information to the serialized JSON. We honor that type information during JSON deserialization. For this, we need to write our own custom serializer and deserializer. Firstly, we'll introduce a new String field called type in the base class Animal.

How do I customize the Gson model?

In short, you'll need to use a custom Gson instance and call the registerTypeAdapter () method. The registerTypeAdapter () expects two parameters. The first one is the type of the overall model we want to customize. The second parameter is an instance of a typed JsonDeserializer. The critical part is the implementation of the JsonDeserializer.


1 Answers

Here is the code for custom deserialization (for Gender) with sample invocation.

1) Gender deserializer is case insensitive

2) Invalid values handled (i.e. input json contains other than male and female)

Main method:-

public static void main(String[] args) {
        String jsonString = "{'firstName' : 'john','lastName' : 'stones','gender' : 'male'}";
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(Person.class, new PersonModelDeserializer())
                .create();

        Person person = gson.fromJson(jsonString, Person.class);
        System.out.println(person.toString());

    }

Gender Enum:-

public enum Gender {
    MALE, FEMALE
}

Deserializer:-

If the input json doesn't have male or female, the valueOf method throws IllegalArgumentException which has been handled as well.

The Gender deserialization is case insensitive as well.

public class PersonModelDeserializer implements JsonDeserializer<Person> {

    @Override
    public Person deserialize(JsonElement paramJsonElement, Type paramType,
            JsonDeserializationContext paramJsonDeserializationContext) throws JsonParseException {

        Person person = new Gson().fromJson(paramJsonElement.getAsJsonObject(), Person.class);

        try {
            Gender gender = null;
            if (paramJsonElement.getAsJsonObject().get("gender") != null) {
                gender = Gender.valueOf(paramJsonElement.getAsJsonObject().get("gender").getAsString().toUpperCase());
            }

            person.setGender(gender);
        } catch (IllegalArgumentException ie) {
            System.out.println(ie.getMessage());
            System.out.println("Gender cannot be serialized ..");
        }

        return person;
    }

}

Person class:-

public class Person implements Serializable{
    private static final long serialVersionUID = 5447375194275313051L;

    private String firstName;
    private String lastName;

    private Gender gender;

    ... getters and setters
}
like image 89
notionquest Avatar answered Sep 18 '22 14:09

notionquest