如何使用 Jackson 将 JSON 键值数组动态映射到子对象?
Posted
技术标签:
【中文标题】如何使用 Jackson 将 JSON 键值数组动态映射到子对象?【英文标题】:How to dynamically map JSON array of key values to sub-object using Jackson? 【发布时间】: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<MessageAttribute> 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"])
【问题讨论】:
你考虑过编写自定义反序列化器的想法 没有走那么远,幸运的是不再需要:) 【参考方案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 错误,所以不是双重包装,而是将属性更改为具有许多动态字段的单个对象,工作:)以上是关于如何使用 Jackson 将 JSON 键值数组动态映射到子对象?的主要内容,如果未能解决你的问题,请参考以下文章
Jackson Json:如何将数组转换为 JsonNode 和 ObjectNode?
将json字符串解析为具有复杂数据结构的java(jackson)
如何使用 Jackson 解析 JSON 数组项中的原始值?
如何使用 Jackson 反序列化来自 json 对象的对象数组