3

I have a response that returns a json object in following format:

{
    "playerId": "001",
    "name": "michel",
    "age": 21,
    "nation": "USA",
    "ratings": [
        {
            "type": "speed",
            "score": "0121"
        },
        {
            "type": "accuracy",
            "score": "85"
        }
    ],
    "teaminfo": {
        "teamName": "HON",
        "isValid": "true"
    }
}

and I have a Java Class as :

public class MyRider {
    public String playerId;
    public String name;
    public int age;
    public String speed;
    public String accuracy;
    public String teamName;
    public String isValid;
    //getter, setter... 
}

I want to map the JSON object into Java object using GSON.

I tried using JsonDeserializationContext deserialize, and it returned null for the nested values in JSON.

9
  • Thanks Justin for refactoring the question. Commented Sep 14, 2018 at 14:33
  • what did you mean by different format ? Commented Sep 14, 2018 at 14:35
  • can you update your code? Commented Sep 14, 2018 at 16:00
  • @benjaminc: In json has list of type and score, but in java class its individual string eg. type: speed turns into string speed and score is its value. Commented Sep 14, 2018 at 19:51
  • @deadpool : what kind of update do you need ? Commented Sep 14, 2018 at 19:51

1 Answer 1

3

Without custom deserializer

If you cannot change the JSON to return exactly what you want, I suggest you create classes to match it:

MyRider:

public class MyRider {
    private String playerId;
    private String name;
    private int age;
    private String nation;
    private List<Rating> ratings;
    private TeamInfo teaminfo;

    // getters, setters, toString override
}

Rating:

public class Rating {
    private String type;
    private String score;

    // getters, setters, toString override
}

TeamInfo:

private static class TeamInfo {
    private String teamName;
    private String isValid;

    // getters, setters, toString override
}

Then simply deserialize as normal:

MyRider rider = gson.fromJson(json, MyRider.class);

If you need exactly the fields you've specified in MyRider in your question, consider a transformer class to map the full class above to your needs.

With custom deserializer

It's also possible to do this with a custom deserializer, but slightly pointless as GSON provides the normal mapping for you which you can then adapt.

Here is an example with a deserializer:

public class MyRiderDeserializer implements JsonDeserializer<MyRider> {

    @Override
    public MyRider deserialize(JsonElement json, Type typeOfT, 
                               JsonDeserializationContext context)
                               throws JsonParseException {
        MyRider rider = new MyRider();
        if(json.isJsonObject()) {
            JsonObject riderObj = json.getAsJsonObject();

            rider.setPlayerId(riderObj.get("playerId").getAsString());
            rider.setName(riderObj.get("name").getAsString());
            rider.setAge(riderObj.get("age").getAsInt());

            JsonArray ratingsArray = riderObj.get("ratings").getAsJsonArray();
            for(JsonElement ratingElem : ratingsArray) {
                JsonObject ratingObj = ratingElem.getAsJsonObject();
                String type = ratingObj.get("type").getAsString();
                switch(type) {
                    case "speed":
                        rider.setSpeed(ratingObj.get("score").getAsString());
                        break;
                    case "accuracy":
                        rider.setAccuracy(ratingObj.get("score").getAsString());
                        break;
                    default:
                        break;
                }
            }

            JsonObject teamInfo = riderObj.get("teaminfo").getAsJsonObject();
            rider.setTeamName(teamInfo.get("teamName").getAsString());
            rider.setIsValid(teamInfo.get("isValid").getAsString());

        }
        return rider;
    }
}

Note this does not include any checks to validate whether the properties are actually there and is the simplest possible custom deserializer I could think of. To use it, you must register the type adapter at Gson creation time:

Gson gson = new GsonBuilder()
                .registerTypeAdapter(MyRider.class, new MyRiderDeserializer())
                .create();

MyRider myRider = gson.fromJson(reader, MyRider.class);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.