简体   繁体   English

使用GSON将JSON对象转换为具有不同格式的Java对象

[英]Convert JSON object to Java object with different format using GSON

I have a response that returns a json object in following format: 我有一个响应,以下列格式返回一个json对象:

{
    "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 : 我有一个Java类:

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. 我想使用GSON将JSON对象映射到Java对象。

I tried using JsonDeserializationContext deserialize, and it returned null for the nested values in JSON. 我尝试使用JsonDeserializationContext反序列化,并为JSON中的嵌套值返回null

Without custom deserializer 没有自定义反序列化器

If you cannot change the JSON to return exactly what you want, I suggest you create classes to match it: 如果您无法更改JSON以准确返回所需内容,我建议您创建匹配它的类:

MyRider: 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: 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. 如果您需要在问题中确切地指定MyRider中指定的字段,请考虑使用变换器类将上面的完整类映射到您的需要。

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. 也可以使用自定义反序列化程序执行此操作,但稍微没有意义,因为GSON为您提供了可以适应的法线映射。

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 gson = new GsonBuilder()
                .registerTypeAdapter(MyRider.class, new MyRiderDeserializer())
                .create();

MyRider myRider = gson.fromJson(reader, MyRider.class);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM