覆盖GSON序列化的继承中的字段类型

时间:2014-05-28 12:40:44

标签: java json serialization deserialization gson

我想通过以下课程实现以下目标:

public class A {
   Data data;
}

public class A extends B {
   boolean data;
}

反序列化时,我想得到以下陈述。

new Gson().fromJson("{\"data\": "false\"}", B.class)
new Gson().fromJson("{\"data\": {}}", A.class)

目前,它当然不起作用,得到一个

IllegalArgumentException: declares multiple JSON fields named data

如何实现它,忽略同名的超类字段?我估计我需要提供shouldSkipField实现,但我现在无法弄清楚逻辑。

1 个答案:

答案 0 :(得分:1)

我认为不应该更改字段的名称,并且A类不应该知道它的子节点。而且我认为Gson仍然不支持二传手注射。所以我没有看到任何与Gson这样做的方法。因为我知道你不能覆盖java中的字段。但杰克逊确实支持二传手注射,而杰克逊你可以非常轻松地做到这一点。只需覆盖getter和setter并将其标记为忽略。要测试的代码:

public static void main(String[] args) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    B b = mapper.readValue("{\"data\": \"false\"}", B.class);
    A a = mapper.readValue("{\"data\": {\"id\":5}}", A.class);
    System.out.println(b);
    System.out.println(a);
}

public static class A{
    private Data data;

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "A{" +
                "data=" + data +
                '}';
    }
}

public static class B extends A{
    private boolean data;

    @JsonIgnore
    @Override
    public Data getData() {
        return super.getData();
    }

    @JsonIgnore
    @Override
    public void setData(Data data) {
        super.setData(data);
    }

    public boolean isData() {
        return data;
    }

    public void setData(boolean data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "B{" +
                "data=" + data +
                '}';
    }
}

public static class Data{
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Data{" +
                "id=" + id +
                '}';
    }
}

out is:

B{data=false}
A{data=Data{id=5}}

如果Gson也支持setter注射,那么就可以使用Gson。