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

3

我有一个返回以下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 :

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... 
}

我想使用GSON将JSON对象映射为Java对象。
我尝试使用JsonDeserializationContext反序列化,但它返回JSON中嵌套值的null。

感谢 Justin 进行重构问题。 - Krishman Pradhan
你说的“不同格式”是什么意思? - benjamin c
你能更新一下你的代码吗? - Ryuzaki L
@benjaminc:在JSON中,有类型和分数的列表,但在Java类中,它们是单独的字符串,例如type:speed变成了字符串速度,而score则是它的值。 - Krishman Pradhan
你是否尝试使用 fromJson(String json, Class classOfT) 方法?例如,String jsonString = "{"playerId":"001","name":"michel", "age":"21"}"; MyRider myRider = gson.fromJson(jsonString, MyRider.class); - Kris
显示剩余4条评论
1个回答

3

没有自定义反序列化器

如果你无法更改JSON以返回所需内容,建议创建与之匹配的类:

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
}

评级:

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

    // getters, setters, toString override
}

团队信息:

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

    // getters, setters, toString override
}

然后,只需像平常一样反序列化即可:
MyRider rider = gson.fromJson(json, MyRider.class);

如果你需要在你的问题中精确地使用MyRider中指定的字段,考虑使用一个变换器类将上面的完整类映射到你的需求。

使用自定义反序列化器

使用自定义反序列化器也是可行的,但有点毫无意义,因为GSON已经为你提供了常规映射,你只需要进行相应的适配即可。
下面是一个使用反序列化器的例子:
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;
    }
}

请注意,此处不包括任何验证属性是否实际存在的检查,这是我能想到的最简单的自定义反序列化器。要使用它,您必须在 Gson 创建时注册类型适配器:

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接