Java 使用 jackson 反序列化 List<Interface>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19866669/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 20:52:19  来源:igfitidea点击:

Deserialize List<Interface> with Hymanson

javajsonserializationHymanson

提问by varunl

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. (This should ideally make the problem easier, because there is no runtime type checking required)

IBar 有两个实现,但是在反序列化时我总是想使用第一个实现。(理想情况下,这应该使问题更容易,因为不需要运行时类型检查)

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.

采纳答案by varunl

@JsonDeserialize(contentAs=Bar.class)
List<IBar> bars;

回答by Mena

Why don't you just use a TypeReference?

你为什么不只使用一个TypeReference

For instance...

例如...

Json file test.jsonin /your/path/:

Json 文件test.json位于/your/path/

[{"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 mainmethod:

main方法的输出:

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

回答by HiJon89

Put the annotation on the IBarinterface declaration rather than the field, ie:

将注解放在IBar接口声明而不是字段上,即:

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