【问题标题】:How to dynamically map JSON array of key values to sub-object using Jackson?如何使用 Jackson 将 JSON 键值数组动态映射到子对象?
【发布时间】:2019-06-26 10:12:52
【问题描述】:

假设我们有一个如下所示的 JSON 结构:

{
 "field1": "val1",
 "field2": "v2",
 "f3": "v3",
 "f4": "v4",
 "arrayOfStuff": [
  {
   "f5": "v5",
   ....
   "f10": "v10"
  }
 ],
 "attributes": [
  {"att1": "att1"},
  {"att2": "attr2"},
  {"att3": "att3"}
 ],
 "options": [
  "ignoreMismatchFile"
 ]
}

我们匹配的java类看起来像:

public class Message {
   @IsUniqueId
   private String field1; //
   private String field2;
   private String field3;
   private String field4;
   private List<AnotherObject> f5;
   @JsonProperty("attributes")
   private LinkedHashMap<String, String> attributes;
   private List<String> options;
   ....
}

解析代码如下:

protected Message loadSavedMessageAsMessageObject(String path) throws IOException {
    File file = ResourceUtils.getFile(path);
    if (file.exists()) {
        ObjectMapper mapper = this.getObjectMapper();
        return mapper.readValue(file, Message.class);
    }

    return null;
}

我们尝试了不同的方法来实现这一点,最初我们尝试将属性设置为 private List&lt;MessageAttribute&gt; attributes;,但这也不起作用(我们切换到基于 Another answer 的地图 - 不起作用)

我们的目标是保持属性是动态的,而不是硬编码的属性列表。

MessageAttribute 类是这样的:

public class MessageAttribute {
    private String key;
    private String value;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

我们目前得到的异常是:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.LinkedHashMap` out of START_OBJECT token
at [Source: (File); line: 32, column: 3] (through reference chain: com.org.Message["attributes"])

【问题讨论】:

  • 你考虑过编写自定义反序列化器的想法
  • 没有走那么远,幸运的是不再需要:)

标签: java json spring-boot jackson jackson2


【解决方案1】:

对应于上述 JSON 的 Message POJO 格式错误,我做了一些更改 attributes 应该是 List of Map 并且 AnotherObject 的列表应该指向 arrayOfStuff

public class Message {
 @IsUniqueId
 private String field1; //
 private String field2;
 private String field3;
 private String field4;
 private List<AnotherObject> arrayOfStuff;  //or you can have List<Map<String,String>> arrayOfStuff
 @JsonProperty("attributes")
 private List<LinkedHashMap<String, String>> attributes; // this is list of map objects
 private List<String> options;
  ....
  }

【讨论】:

  • 谢谢!有了这个答案,发现我们的 JSON 错误,所以不是双重包装,而是将属性更改为具有许多动态字段的单个对象,工作:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-21
  • 2019-04-28
  • 2019-08-10
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
相关资源
最近更新 更多