Jackson和Iterable:如何反序列化

时间:2018-11-20 10:38:03

标签: java json jackson jackson-databind

我有一个类Box,该类具有一个实现elements的类型Elements的字段Iterable(请参见下面的代码)。后者包含List,也称为elements

如果我将elements的字段Elements设置为private,则序列化会将其视为数组而不是POJO

由版本A完成的序列化

{
  "elements" : [ "a", "b", "c" ]
}

但是,我无法反序列化此字符串。错误是:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `ser_deser_test.Elements` out of START_ARRAY token
 at [Source: (String)"{
  "elements" : [ "a", "b", "c" ]
}"; line: 2, column: 16] (through reference chain: 

如果我改为将elements设置为public,则elements中的Box将被视为POJO,而我有两个有趣的{ {1}}。反序列化在这种情况下有效。

B版本的序列化

elements

我的问题是:如何获得反序列化才能用于版本A?

代码

Box.java

{
  "elements" : {
    "elements" : [ "a", "b", "c" ]
  }
}

Elements.java

package ser_deser_test;

public class Box {
    public Box() {
        super();
    }

    public Elements elements;

    public Box(Elements elements) {
        super();
        this.elements = elements;
    }

}

TestSerDeser.java

package ser_deser_test;

import java.util.Iterator;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonFormat;

public class Elements implements Iterable<String> {
    // private List<String> elements; // Version A
    // public List<String> elements;  // Version B

    public Elements() {
        super();
    }

    public Elements(List<String> elements) {
        super();
        this.elements = elements;
    }

    @Override
    public Iterator<String> iterator() {
        return elements.iterator();
    }

}

2 个答案:

答案 0 :(得分:2)

为什么不使用List<String>的简单属性?

public class Elements {

   public List<String> elements;

或者,如果您不需要特定的对象,也可以作为@EugenCovaci注释

 public class Box {
   public List<String> elements; //directly into Box class

要保留private List<String> elements;,只需添加getter用作属性:

public List<String> getElements() {
   return elements;
}

您还可以添加@JsonProperty

  @JsonProperty
  private List<String> elements;

答案 1 :(得分:1)

您的代码可以与以下项目配合使用

package ser_deser_test;

import java.util.Iterator;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonFormat;

public class Elements implements Iterable<String> {
    // private List<String> elements; // Version A
    public List<String> elements;  // Version B

    public Elements() {
        super();
    }

    public Elements(List<String> elements) {
        super();
        this.elements = elements;
    }

    @Override
    public Iterator<String> iterator() {
        return elements.iterator();
    }

}

并以Version A失败而失败,因为默认情况下,杰克逊没有访问私有字段的权限。要使其与Version A一起使用,请修改TestSerDeser类,如下所示:

ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

为了允许Jackson访问私有字段List<String> elements,甚至更好的是,为该字段添加公共获取者。