java - jackson 和可迭代 : how to deserialize

标签 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,则 Boxelements 将被视为一个 POJO,我在其中有两个有趣的 elements 级别。然而,反序列化在这种情况下有效。

按版本 B 序列化

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

我的问题是:如何让反序列化对版本 A 起作用?

代码

Box.java

package ser_deser_test;

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

    public Elements elements;

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

}

Elements.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();
    }

}

TestSerDeser.java

package ser_deser_test;

import java.io.IOException;
import java.util.Arrays;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class TestSerDeser {

    public static void main(String[] args) {
        Elements elements = new Elements(Arrays.asList("a", "b", "c"));
        Box      box = new Box(elements);

        ObjectMapper om = new ObjectMapper();

        om.enable(SerializationFeature.INDENT_OUTPUT);
        try {
            // Serialize
            String s = om.writeValueAsString(box);

            // Deserialize
            Box box2 = om.readValue(s, Box.class);

            boolean dummy = false;

        } catch (JsonProcessingException e2) {
            e2.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }         
    }
}

最佳答案

为什么不使用 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;

关于java - jackson 和可迭代 : how to deserialize,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53391144/

相关文章:

java - 将 JFrame 传输到 JPanel

json - 如何解析这个 json 响应?

android - JSON 对象 : linked list?

java - jackson 反序列化错误处理

java - Tomcat:在日志中获取 'Character decoding failed';可能的恶意攻击?

java - 使用 Rest API Java 工具包获取 Agile Central 项目 ID 的里程碑列表

ios - 如何将变量分离到其他文件并访问

java - JSON解析异常: Failed to decode VALUE_STRING as base64 (MIME-NO-LINEFEEDS): Illegal character '"' (code 0x22) in base64 content

java - 找不到 com.fasterxml.jackson.core.JsonParseException 的类文件

java - Facebook 应用程序在 Android 中加载缓慢