简体   繁体   English

反序列化列表<Interface>与杰克逊

[英]Deserialize List<Interface> with jackson

I want to deserialize json to class Foo:我想将 json 反序列化为 Foo 类:

class Foo {
   List<IBar> bars;
}

interface IBar {
   ...
}

class Bar implements IBar {
   ...
}

IBar has two implementations, but when deserializing I always want to use the first implementation. IBar 有两个实现,但是在反序列化时我总是想使用第一个实现。 (This should ideally make the problem easier, because there is no runtime type checking required) (理想情况下,这应该使问题更容易,因为不需要运行时类型检查)

I am sure I can write custom deserializers, but felt there must be something easier.我确信我可以编写自定义反序列化器,但觉得一定有更简单的方法。

I found this annotation, which works perfectly when there is no list.我找到了这个注释,当没有列表时它可以完美地工作。

@JsonDeserialize(as=Bar.class)
IBar bar;

List<IBar> bars; // Don't know how to use the annotation here.
@JsonDeserialize(contentAs=Bar.class)
List<IBar> bars;

Why don't you just use a TypeReference ?为什么不直接使用TypeReference

For instance...例如...

Json file test.json in /your/path/ : /your/path/ Json 文件test.json

[{"s":"blah"},{"s":"baz"}]

Main class in package test :test主类:

public class Main {
    public static void main(String[] args) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            List<IBar> actuallyFoos = mapper.readValue(
                    new File("/your/path/test.json"), new TypeReference<List<Foo>>() {
                    });
            for (IBar ibar : actuallyFoos) {
                System.out.println(ibar.getClass());
            }
        }
        catch (Throwable t) {
            t.printStackTrace();
        }
    }

    static interface IBar {
        public String getS();

        public void setS(String s);
    }

    static class Foo implements IBar {
        protected String s;

        public String getS() {
            return s;
        }

        public void setS(String s) {
            this.s = s;
        }
    }

    static class Bar implements IBar {
        protected String s;

        public String getS() {
            return s;
        }

        public void setS(String s) {
            this.s = s;
        }
    }
}

Output of the main method: main方法的输出:

class test.Main$Foo
class test.Main$Foo

Put the annotation on the IBar interface declaration rather than the field, ie:将注释放在IBar接口声明而不是字段上,即:

@JsonDeserialize(as=Bar.class)
interface IBar {
   ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM