【问题标题】:Json desirialization using jackson with List of Abstract class Jackson使用带有抽象类杰克逊列表的杰克逊进行 Json 反序列化
【发布时间】:2016-05-11 10:14:26
【问题描述】:

我有一个类似的 json 结构

{"myobj": { "ford" : [ {"color":"blue","ford_property":"A" } ], "audi": [ {"color":"red", "audi_property":"B"}, {"color":"black", "audi_property":"C"} ] } }

类结构是

abstract class Car implements Serializable { 
    private String color;
    // getter setter here
}
class Ford extends Car { 
    private String fordProperty;
    // getter setter here
}
class Audi extends Car {
    private String audiProperty;
    // getter setter here
}

我的响应类

class Response implements Serializable {
     private Map<String, List<Car>> myObj;
     // getter setters
}

尝试在Car 类上使用@JsonSubTypes,但它期望class 名称的type 作为对象{"color":"blue","ford_property":"A" } 的一部分。

谢谢

【问题讨论】:

  • 我不知道我是否遇到了你的问题,但无论如何我都会建议 [Polymorphic JSON with jackson] (programmerbruce.blogspot.it/2011/05/…)
  • 我用杰克逊尝试了多态 JSON,问题是我没有 type 作为课程的一部分。但是type 是类列表的键。所以我有{dog:[{name:foo}]}而不是[{type:dog,name:foo}]
  • 好的,如果我是你,我会使用自定义反序列化器。 Jackson – Custom Deserializer

标签: java json jackson objectmapper


【解决方案1】:

选项 1

您可以通过更改Response 代码和启用SerializationFeature.WRAP_ROOT_VALUE + DeserializationFeature.UNWRAP_ROOT_VALUE 设置来完成此操作

这里是演示:

public static void main(String[] args) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
    mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
    Response resp = mapper.readValue(json, Response.class);
}

public abstract static class Car implements Serializable {
    public String color;
}

public static class Ford extends Car {
    @JsonProperty("ford_property")
    public String fordProperty;
}

public static class Audi extends Car {
    @JsonProperty("audi_property")
    public String audiProperty;
}

@JsonRootName("myobj")
public static class Response implements Serializable {
    public List<Audi> audi;
    public List<Ford> ford;
}

选项 2

不要更改结构中的任何内容,不需要WRAP_ROOT_VALUE,但这会反序列化对象 2 次​​p>

public static class Response implements Serializable {
    private Map<String, List<Car>> myObj;

    @JsonAnySetter
    private void setter(String key, JsonNode value) {
        try {
            if (key.equals("ford")) {

                myObj.put(key, mapper.readValue(value.toString(), 
                                     new TypeReference<List<Ford>>() {}));
            } else if (key.equals("audi")){
                myObj.put(key,  mapper.readValue(value.toString(), 
                                   new TypeReference<List<Audi>>() {}));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

选项 3

Response 的自定义反序列化器与上面的@JsonAnySetter 代码几乎相同,但可以在反序列化器中对其进行优化。

【讨论】:

    猜你喜欢
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多