【问题标题】:Convert JSON object to Java object with different format using GSON使用 GSON 将 JSON 对象转换为不同格式的 Java 对象
【发布时间】:2018-09-14 14:27:32
【问题描述】:

我有一个返回以下格式的 json 对象的响应:

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

我有一个 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... 
}

我想使用 GSON 将 JSON 对象映射到 Java 对象。

我尝试使用 JsonDeserializationContext 反序列化,它为 JSON 中的嵌套值返回 null

【问题讨论】:

  • 感谢贾斯汀重构问题。
  • 不同格式是什么意思?
  • 你能更新你的代码吗?
  • @benjaminc:在 json 中有类型和分数的列表,但在 java 类中它的单个字符串,例如。 type:speed变成string speed,score就是它的值。
  • @deadpool:你需要什么样的更新?

标签: java json gson deserialization


【解决方案1】:

没有自定义反序列化器

如果您无法更改 JSON 以完全返回您想要的,我建议您创建类来匹配它:

我的骑手:

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);

【讨论】:

    猜你喜欢
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多