[英]Deserializing complex map structure from JSON
I have a JSON structure like this: 我有一个像这样的JSON结构:
[
{
"topLevelOne": {
"property1": false,
},
"topLevelTwo": [
{
"property2": false,
"property3": false,
"property4": false,
},
{
"property2": false,
"property3": false,
"property4": false,
}
]
},
{
"topLevelOne": {
"property1": false,
},
"topLevelTwo": [
{
"property2": false,
"property3": false,
},
{
"property2": false,
"property3": false,
},
]
}
]
I am trying to convert this structure with Jackson into Map<CustomObject, List<CustomObject>>
where topLevelOne
corrsponds to Key
, and the value is topLevelTwo
( List<CustomObject>
) 我试图将这个结构与Jackson转换为
Map<CustomObject, List<CustomObject>>
,其中topLevelOne
为Key
,值为topLevelTwo
( List<CustomObject>
)
So I tried this: 所以我尝试了这个:
ObjectMapper JSONMapper = new ObjectMapper();
Map<CustomObject, List<CustomObject>> map = JSONMapper.readValue(json, new TypeReference<Map<CustomObject, List<CustomObject>>>(){});
However I'm getting this error message: com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class CustomObject
] 但是我收到此错误消息:
com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class CustomObject
] com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class CustomObject
Could anyone point out what I'm doing wrong here? 谁能指出我在这里做错了什么? Maybe a code example how this can be achieved?
也许一个代码示例如何实现这一目标?
The json isn't valid because you have mixed types at the same level in your structure. json无效,因为您在结构中具有相同级别的混合类型。 I think you might accomplish what you want with a Map of Maps.
我想你可以通过地图地图完成你想要的任务。 I'm not sure about your custom Objects, so I'll use Strings in case it helps.
我不确定你的自定义对象,所以我会使用字符串以防万一。
If you define your json like this: 如果你像这样定义你的json:
[{
"topLevelOne": [{
"property1": false
}],
"topLevelTwo": [{
"property2": false,
"property3": false,
"property4": false
},
{
"property2": false,
"property3": false,
"property4": false
}
]
},
{
"topLevelOne": [{
"property1": false
}],
"topLevelTwo": [{
"property2": false,
"property3": false
},
{
"property2": false,
"property3": false
}
]
}
]
you could read it with something like this: 你可以用这样的东西读它:
Map<String, Map<String,String>> map = mapper.readValue(json, new TypeReference <Map<String, Map<String,String>>>(){});
The built in Jackson Map
deserialiser uses field names as keys and maps them to the related field values. 内置的Jackson
Map
反序列化器使用字段名称作为键并将它们映射到相关的字段值。
Your json is structured differently—it's a list of entries. 你的json结构不同 - 它是一个条目列表。 The simplest way to deserialise your map would be to read the list and build the map afterwards.
反序列化地图的最简单方法是读取列表并在之后构建地图。
You'll need a helper object to model the entries: 您需要一个辅助对象来为条目建模:
class CustomEntry {
private CustomKey topLevelOne;
private List<CustomObject> topLevelTwo;
@JsonCreator
public CustomEntry(@JsonProperty("topLevelOne") CustomKey topLevelOne, @JsonProperty("topLevelTwo") List<CustomObject> topLevelTwo) {
this.topLevelOne = topLevelOne;
this.topLevelTwo = topLevelTwo;
}
public CustomKey getTopLevelOne() {
return topLevelOne;
}
public List<CustomObject> getTopLevelTwo() {
return topLevelTwo;
}
}
Then, 然后,
String json = ...
ObjectMapper mapper = new ObjectMapper();
// Read the list of map entries
List<CustomEntry> entries = mapper.readValue(json, new TypeReference<List<CustomEntry>>(){});
// Build the map
Map<CustomKey, List<CustomObject>> map = entries.stream().collect(Collectors.toMap(e -> e.topLevelOne, e -> e.topLevelTwo));
You could create a custom deserialiser to read the map directly from the list, but I'm not sure if it's worth the extra effort. 您可以创建一个自定义反序列化器直接从列表中读取地图,但我不确定是否值得付出额外的努力。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.