【问题标题】:Deserialize List<Interface> with jackson用杰克逊反序列化 List<Interface>
【发布时间】:2013-11-20 21:53:40
【问题描述】:

我想将 json 反序列化为 Foo 类:

class Foo {
   List<IBar> bars;
}

interface IBar {
   ...
}

class Bar implements IBar {
   ...
}

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

我确信我可以编写自定义反序列化器,但我觉得肯定有更简单的东西。

我找到了这个注解,它在没有列表的情况下非常有效。

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

List<IBar> bars; // Don't know how to use the annotation here.

【问题讨论】:

    标签: java json serialization jackson


    【解决方案1】:
    @JsonDeserialize(contentAs=Bar.class)
    List<IBar> bars;
    

    【讨论】:

    • 如果我有多个 IBar 实现,解决方案是什么?我有一个包含 IBar 对象列表的对象。它可以是动态的 Bar1.class 或 Bar2.class。有什么办法可以解决这个问题?
    • @Maz 您是否设法通过多种实现解决了您的问题
    • 是的。我使用了 Jackson 多态性解决方案,它奏效了。
    • 这对我不起作用。遇到 JsonMappingExceptoion com.fasterxml.jackson.databind.JsonMappingException: 无法缩小 [collection type; 的值类型;类 java.util.List,包含 [simple type, class com.test...IBar]] 和具体类型注释(值 com.test...Bar),来自 '': Class com.test..Bar not [简单类型,com.test...IBar 类]的子类型
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      你为什么不直接使用TypeReference

      比如……

      /your/path/ 中的 Json 文件 test.json

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

      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;
              }
          }
      }
      

      main 方法的输出:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-07
        • 1970-01-01
        • 2016-01-27
        • 1970-01-01
        • 1970-01-01
        • 2012-11-19
        • 2016-10-23
        • 1970-01-01
        相关资源
        最近更新 更多