(杰克逊)如何反序列化包裹的数组?

时间:2015-12-14 18:37:21

标签: java json jackson deserialization

目前,我收到了这个JSON输入,我无法控制它:

{
    "A" : {
        "B" : {
            "B" : [{
                    "Whatever" : "String",
                    "Number": 123
                }
            ],
            "SiblingObject" : true
        }
    }
}

基本上,我想将B对象内部的B数组直接反序列化为A类,而不必创建另一个额外的类来包装B对象。像这样:

public class A {

    private List<B> bList;

    public List<B> getB() {
        return bList;
    }

    @JsonProperty("B")
    public void setB(List<B> bList) {
        this.bList = bList;
    }
}

我已经尝试过了

public class A {

    private List<B> bList;

    public List<B> getB() {
        return bList;
    }

    @JsonProperty("B")
    public void setB(Map<String, Object> bList) {
        this.bList = (List<B>) bList.get("B");
    }
}

但无济于事。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

有一种方法可以做到这一点。但是,它需要遍历输入JSON两次。

在第一遍中,您创建没有List的普通A实例。 在第二遍中,您使用Jackson的节点遍历来到达正确的B对象并从那里进行解析。

请参阅以下代码:

public class WrapperJsonTest {

    public static void main(String[] args) {

        ObjectMapper om = new ObjectMapper();
        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("wrapper.json");
        A a = null;
        try {
            a = om.readValue(in, A.class);
        } catch (Exception e){
            e.printStackTrace();
        }

        in = Thread.currentThread().getContextClassLoader().getResourceAsStream("wrapper.json");
        try {
            JsonNode node = om.readValue(in, JsonNode.class).get("B").get("B");
            JsonParser parser = node.traverse();
            List<B> bList = om.readValue(parser, List.class);
            a.setB(bList);
            System.out.println(a.isSibling());
            System.out.println(a.getB());
        } catch (Exception e){
            e.printStackTrace();
        }

    }

    @JsonIgnoreProperties
    public static class A {

        @JsonIgnore
        private List<B> bList;
        private boolean sibling;

        public List<B> getB() {
            return bList;
        }

        public void setB(List<B> bList) {
            this.bList = bList;
        }

        public boolean isSibling() {
            return sibling;
        }

        public void setSibling(boolean sibling) {
            this.sibling = sibling;
        }
    }

    public static class B {

        private String whatever;

        public String getWhatever() {
            return whatever;
        }

        public void setWhatever(String whatever) {
            this.whatever = whatever;
        }

        @Override
        public String toString() {
            return whatever;
        }

    }

}