2017-04-21 3 views
0

표준 Json 배열을 사용자 정의 목록 유형 (infact은 java.util.List가 아닌 javaslang.collection.List)으로 매핑해야합니다. 복잡성에 더해 정적 bean은 없지만 목록 유형을 javaslang 유형으로 정의 할 수 있지만 generic 맵에 맵핑해야하지만 목록 인스턴스는 javaslang.collection.List 유형이어야합니다.Jackson custom 목록 인스턴스 유형

새로운 맞춤형 디시리얼라이저를 만들려고했으나 일반적인지도로 탈바꿈하려고 했으므로 맞춤형 디시리얼라이저를 전혀 다루지 않습니다.

예를 들어, 다음은 테스트하려는 테스트 케이스입니다.

@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

지도에 대한 디시리얼라이저를 작성하면 원하는 결과를 얻을 수 있습니다. 이런 식으로 뭔가 :

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

참고 : 필요에 따라 형 HashMaps을의 경우에도 내부 개체를 구문 분석하는 코드 위

  • , 구현은 변경 될 수 있습니다.
  • 문자열, 정수 등을 처리하기 위해 더 많은 경우를 추가 할 수 있습니다. 필요에 따라 예외를 처리 할 수 ​​있습니다. 위 디시리얼라이저의

샘플 사용 :

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