Json 动态响应行的反序列化器

Json Deserializer for dynamic response rows

使用GSON为json响应创建反序列化器的正确方法是否如下所示?

{
     user: "me",
     red: {"some object"},
     green: {...}
     ...
     ....
     .....
  }

我想我需要一个类似于

的对象
class ColorResponse {
   String user;
   Map<String, Color> colorMap;
}

恐怕您尝试实现的解决方案是不可能的,因为 colorMap 不是 JSON 的 属性,JSON 应该像

{
    user: "me",
    colorMap: {
        red: {"some object"},
        green: {...}
        ...
    }
}

那么您现在需要的是一个自定义反序列化器,它迭代 JSON 响应的对象。 Custom JSON deserializer using Gson 这是一个很好的例子,说明如何使用自定义代码和 GSON 进行反序列化。

基本上你必须为 class ColorResponse 注册一个自定义解串器,你可以这样做:

deserialize() {
    ColorResponse response = new ColorResponse();
    List<Color> colors = new ArrayList<>();
    response.setName(json.getAsJsonObject().get("name").asString());
    for (Entry<String, JsonElement> entry : json.entrySet()) {
        if (!entry.getKey().equals("name")) {
           colors.add(new Color(entry.getKey(), entry.getValue()));
        }
    }
}

这段代码只是为了展示如何做到这一点,我已经在运行中编写了它,但我不确定它是否会编译,但关键是如果你只拥有那个名字将是不变的,所以其余的是颜色,然后只需将所有颜色添加到列表、地图或您想要的任何内容即可。

所以我的解决方案是自定义解串器

  public class ColorDeserializer implements JsonDeserializer<ColorResponse> {

        private List<String> colors;

        public ColorDeserializer(List<String> colors) {
            this.colors = colors;
        }

        @Override
        public ColorResponse deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

            JsonObject object = json.getAsJsonObject();
            long timestamp = object.get("timestamp").getAsLong();
            String username = object.get("user").getAsString();

            ColorResponse colorResponse = new ColorResponse(timestamp, username);

            for (String color: colors) {
                JsonObject jsonObject = object.get(color).getAsJsonObject();
                if (jsonObject != null) {
                    colorResponse.getColorMap().put(color, context.<Color>deserialize(jsonObject, Color.class));
                }
            }

            return colorResponse;
        }
    }