Favolas Favolas - 6 months ago 13
Java Question

Gson deserialize fields and create objects

I'm using

Gson
to handle json.
I'm receiving a json in this format:

{
"name": "Paul Matt",
"age": "120",
"phone": "00123456789",
"email": "paul@matt.com"
}


I cannot change the format of this json.

If deserializing to this class:

@SerializedName("name")
@Expose
public String name;
@SerializedName("age")
@Expose
public String age;
@SerializedName("phone")
@Expose
public String phone;
@SerializedName("email")
@Expose
public String email;


But what I really want is that the json is deserialized to a class like this one:

public Person person; //name and age goes here
public PersonContacts contacts; // email and phone goes here


Whats the best way to achieve this?

Answer

In this case you should parse your JSON manually. In Gson library we have two possibilities for achieving this:

  1. Create streaming deserializer and parse every token;
  2. Create implementation of JsonDeserializer and parse ready JsonElement object.

Here some examples:

The first approach:

public class StreamUserDeserializer extends TypeAdapter<User> {

    @Override
    public void write(JsonWriter out, List<CMPoint> value) throws IOException {

    }

    @Override
    public User read(JsonReader in) throws IOException {
        User user = new User();

        in.beginObject();
        while (in.hasNext()) {
            switch (in.nextName()) {
                case "name":
                    user.getPerson().setName(in.nextString());
                    break;

                case "age":
                    user.getPerson().setAge(in.nextInt());
                    break;

                case "phone":
                    user.getPersonContacts().setPhone(in.nextString());
                    break;

                case "email":
                    user.getPersonContacts().setEmail(in.nextString());
                    break;

                default:
                    in.skipValue();
            }
        }
        in.endObject();

        return user;
    }

}

The second approach:

public class JsonElementUserDeserializer implements JsonDeserializer<User> {

    @Override
    public User deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
  throws JsonParseException {
      JsonObject userObject = json.getAsJsonObject();

      User user = new User();
      user.getPerson().setName(userObject.get("name").getAsString());
      user.getPerson().setAge(userObject.get("age").getAsInt());
      user.getPersonContacts().setPhone(userObject.get("phone").getAsString());
      user.getPersonContacts().setAge(userObject.get("email").getAsString());
      return user;
   }
}