我需要将标准Json数组映射到自定义List类型(实际上不是java.util.List,而是javaslang.collection.List)。除了复杂性之外,我们还没有静态bean,我们可以将列表类型定义为javaslang类型,但是我们需要映射到通用Map,但列表实例应该是javaslang.collection.List类型。
我尝试创建新的自定义反序列化器,但由于我们正在尝试使用通用Map,因此根本不会触及该自定义反序列化器。
例如,这是我们希望通过的测试用例。
@Test
@DisplayName("list instance is javaslang list")
void listAsJsList() throws Exception {
Map<String, Object> object = objectMapper.readValue(
"{\"records\": [{\"id\": \"123\"}, {\"id\": \"124\"} ] }", HashMap.class);
assertThat(object.get("records")).isInstanceOf(javaslang.collection.List.class);
}
感谢任何帮助。
答案 0 :(得分:0)
为Map编写反序列化器可以获得所需的结果。像这样:
class MapDeserializer extends JsonDeserializer<Map<String, Object>> {
@Override
public Map<String, Object> deserialize(JsonParser paramJsonParser, DeserializationContext paramDeserializationContext)
throws IOException, JsonProcessingException {
JsonNode node = paramJsonParser.getCodec().readTree(paramJsonParser);
return parseObject(node);
}
private Map<String, Object> parseObject(JsonNode node) {
Map<String, Object> object = new HashMap<String, Object>();
Iterator<Map.Entry<String, JsonNode>> itr = node.fields();
while (itr.hasNext()) {
Map.Entry<String, JsonNode> entry = itr.next();
if (entry.getValue().isArray())
object.put(entry.getKey(), parseArray(entry.getValue()));
else if (entry.getValue().isObject())
object.put(entry.getKey(), parseObject(entry.getValue()));
else
object.put(entry.getKey(), entry.getValue().asText());
}
return object;
}
private List<Object> parseArray(JsonNode node) {
List<Object> list = List.of();
Iterator<JsonNode> itr = node.elements();
while (itr.hasNext()) {
JsonNode currentNode = itr.next();
if (currentNode.isObject())
list = list.prepend(parseObject(currentNode));
else if (currentNode.isArray())
list = list.prepend(parseArray(currentNode));
else
list = list.prepend(currentNode.asText());
}
return list;
}
}
注意:
以上反序列化程序的示例用法:
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Map.class, new MapDeserializer());
mapper.registerModule(module);
Map<String, Object> result = mapper.readValue("{\"records\": [{\"id\": \"123\"}, {\"id\": \"124\"} ] }", Map.class);
if (result.get("records") instanceof javaslang.collection.List) {
System.out.println("records are of type javaslang list");
}
// Prints: records are of type javaslang list