2017-04-21 115 views
0

我需要將標準Json數組映射到自定義List類型(實際上不是java.util.List,除了javaslang.collection.List之外)。除了複雜性之外,我們沒有靜態bean,我們可以將列表類型定義爲javaslang類型,但我們需要映射到通用映射,但列表實例應該是javaslang.collection.List類型。Jackson自定義列表實例類型

我嘗試創建新的自定義反序列化器,但由於我們試圖陷入通用映射中,它根本沒有觸及那個自定義反序列化器。

例如,以下是我們希望通過的測試用例。

@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

爲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; 
    } 
} 

注:

  • 上面的代碼也會解析內部對象類型包含HashMap的情況下,實現可以根據需要改變。
  • 可以添加更多的案例來處理字符串,整數等,作爲那裏的相應類型的實例,並且可以在需要的地方完成異常處理。上述解串器的

示例用法:

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