Jackson ObjectMapper 用方括号包裹每个元素(即使是单个值)
Jackson ObjectMapper wraps every element with square brackets (Even single values)
我有两个 Map 对象,我将它们合并到 Guava 的 Multimap 中。合并后,我试图通过 jackson ObjectMapper
和 GuavaModule
序列化最终地图(否则它无法正确序列化)。然而,问题是键的每个值都被打印为列表的一个元素,即使只有一个值也是如此(objectmapper 将每个值都用方括号括起来)。我得到的基本输出如下,
{
"address": {
"city": ["san francisco"]
},
"company": {
"employees": [
[{
"name": "David",
"lastname": "Foobar",
"age": 22
}, {
"name": "Michael",
"lastname": "FizBuzz",
"age": 35
}]
]
},
"config": {
"key1": ["value1", "value3"],
"key2": ["value2"],
"key4": ["value4"]
}
}
如你所见 "address" -> "city" -> "san francisco" 用方括号包裹, company -> employees
也包裹两次 另外,我试过 SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED, true
未来但没有任何改变。
Person person = new Person();
person.setName("David");
person.setLastname("Foobar");
person.setAge(22);
Person person2 = new Person();
person2.setName("Michael");
person2.setLastname("FizBuzz");
person2.setAge(35);
Map<String, Map<String, Object>> map1 = new ImmutableMap.Builder<String, Map<String, Object>>()
.put("config", ImmutableMap.of(
"key1", "value1",
"key2", "value2"))
.put("address", ImmutableMap.of("city", "san francisco"))
.put("company", ImmutableMap.of("employees", Arrays.asList(person, person2)))
.build();
Map<String, Map<String, Object>> map2 = new ImmutableMap.Builder<String, Map<String, Object>>()
.put("config", ImmutableMap.of(
"key1", "value3",
"key4", "value4"))
.build();
Map<String, Multimap<String, Object>> merged = new HashMap<>();
BiFunction<Multimap<String, Object>,
Multimap<String, Object>,
Multimap<String, Object>> remappingFunction = (value1, value2) -> {
Multimap<String, Object> multimap = HashMultimap.<String, Object>create();
multimap.putAll(value1);
multimap.putAll(value2);
return multimap;
};
map1.forEach((key, value) -> merged.merge(key, Multimaps.forMap(value), remappingFunction));
map2.forEach((key, value) -> merged.merge(key, Multimaps.forMap(value), remappingFunction));
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new GuavaModule());
objectMapper.configure(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED, true);
String str = objectMapper.writeValueAsString(merged);
System.out.print(str);
}
感谢您的帮助。谢谢
根据Jackson documentation,MultimapSerializer
"encloses all value sets in JSON Array, regardless of number of values"。我相信这意味着它实际上忽略了 WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED
功能。
您可以通过在序列化之前将所有内部 Multimap<String, Object>
实例转换为标准 Map<String, Collection<Object>>
实例来避免此问题。您可以使用 Multimap.asMap()
:
Map<String, Map<String, Collection<Object>>> newMerged = new HashMap<>();
merged.forEach((key, value) -> newMerged.put(key, value.asMap()));
String newStr = objectMapper.writeValueAsString(newMerged);
System.out.println(newStr);
这将打印您期望的输出:
{"address":{"city":"san francisco"},"company":{"employees":[{"name":"David","lastname":"Foobar","age":22},{"name":"Michael","lastname":"FizBuzz","age":35}]},"config":{"key1":["value1","value3"],"key2":"value2","key4":"value4"}}
我有两个 Map 对象,我将它们合并到 Guava 的 Multimap 中。合并后,我试图通过 jackson ObjectMapper
和 GuavaModule
序列化最终地图(否则它无法正确序列化)。然而,问题是键的每个值都被打印为列表的一个元素,即使只有一个值也是如此(objectmapper 将每个值都用方括号括起来)。我得到的基本输出如下,
{
"address": {
"city": ["san francisco"]
},
"company": {
"employees": [
[{
"name": "David",
"lastname": "Foobar",
"age": 22
}, {
"name": "Michael",
"lastname": "FizBuzz",
"age": 35
}]
]
},
"config": {
"key1": ["value1", "value3"],
"key2": ["value2"],
"key4": ["value4"]
}
}
如你所见 "address" -> "city" -> "san francisco" 用方括号包裹, company -> employees
也包裹两次 另外,我试过 SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED, true
未来但没有任何改变。
Person person = new Person();
person.setName("David");
person.setLastname("Foobar");
person.setAge(22);
Person person2 = new Person();
person2.setName("Michael");
person2.setLastname("FizBuzz");
person2.setAge(35);
Map<String, Map<String, Object>> map1 = new ImmutableMap.Builder<String, Map<String, Object>>()
.put("config", ImmutableMap.of(
"key1", "value1",
"key2", "value2"))
.put("address", ImmutableMap.of("city", "san francisco"))
.put("company", ImmutableMap.of("employees", Arrays.asList(person, person2)))
.build();
Map<String, Map<String, Object>> map2 = new ImmutableMap.Builder<String, Map<String, Object>>()
.put("config", ImmutableMap.of(
"key1", "value3",
"key4", "value4"))
.build();
Map<String, Multimap<String, Object>> merged = new HashMap<>();
BiFunction<Multimap<String, Object>,
Multimap<String, Object>,
Multimap<String, Object>> remappingFunction = (value1, value2) -> {
Multimap<String, Object> multimap = HashMultimap.<String, Object>create();
multimap.putAll(value1);
multimap.putAll(value2);
return multimap;
};
map1.forEach((key, value) -> merged.merge(key, Multimaps.forMap(value), remappingFunction));
map2.forEach((key, value) -> merged.merge(key, Multimaps.forMap(value), remappingFunction));
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new GuavaModule());
objectMapper.configure(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED, true);
String str = objectMapper.writeValueAsString(merged);
System.out.print(str);
}
感谢您的帮助。谢谢
根据Jackson documentation,MultimapSerializer
"encloses all value sets in JSON Array, regardless of number of values"。我相信这意味着它实际上忽略了 WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED
功能。
您可以通过在序列化之前将所有内部 Multimap<String, Object>
实例转换为标准 Map<String, Collection<Object>>
实例来避免此问题。您可以使用 Multimap.asMap()
:
Map<String, Map<String, Collection<Object>>> newMerged = new HashMap<>();
merged.forEach((key, value) -> newMerged.put(key, value.asMap()));
String newStr = objectMapper.writeValueAsString(newMerged);
System.out.println(newStr);
这将打印您期望的输出:
{"address":{"city":"san francisco"},"company":{"employees":[{"name":"David","lastname":"Foobar","age":22},{"name":"Michael","lastname":"FizBuzz","age":35}]},"config":{"key1":["value1","value3"],"key2":"value2","key4":"value4"}}