2013-03-26 3 views
0

좋은 시간!Jackson : 사용자 지정 디시리얼라이저에서 임의의 노드 값 가져 오기

json 문자열이 {id:'a', type:'b', category:'c'}이고 비즈니스 로직이 카테고리 객체를 작성하기 위해 카테고리 이름 ('c')과 유형 ('b')을 알아야합니다. 분명히 내가 카테고리 deserializer (@JsonDeserialize(using = CategoryCustomDeserializer.class))를 작성해야하고 카테고리의 이름을 얻는 것은 간단하지만 유형의 값을 얻는 방법을 알아낼 수는 없다 ... 나는 이것을 시도했다 : jsonParser.getCodec().readTree(jsonParser),하지만 null을 반환합니다.

올바른 방법을 제안하십시오.

편집 :

public class CategoryNameDeserializer extends JsonDeserializer<Category> { 

    @Override 
    public Category deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     if (jp.getCurrentToken() != JsonToken.END_OBJECT) { 
      String categoryName = jp.getText(); 
      String type = ?????? <------------------------ How to do it 
      return Service.getInstance().getCategory(categoryName, type); 
     } 

     return null; 
    } 
} 
+1

사용자 지정 디시리얼라이저를 작성해야한다는 것은 분명하지 않습니다. 실제로 Jackson POJO 바인딩을 사용하는 것이 훨씬 간단하고 불필요한 추가 필드는 무시합니다. 어떤 이유에서든 사용자 정의 디시리얼라이저를 계속 사용하기로 결정하면 범주 이름을 얻는 것과 같은 방식으로 형식 값을 가져올 수 있습니다. 질문에 현재 디시리얼라이저 코드를 포함 할 수 있습니다. – Perception

+0

@Perception, 실제로 사용자 지정 deserializer가 필요합니다. 왜냐하면 Category 객체를 작성하는 동안해야 할 일이 있기 때문입니다. 디시리얼라이저 코드를 추가했습니다. – Dmitry

답변

0

글쎄, 내가 대답을 발견했습니다 여기 는 디시리얼라이저이다. 이것은 해결책이지만 작동합니다. 하나는 이러한 방법으로 파서를 재설정 할 수 있습니다 : 다음

private JsonParser getResetParser(JsonParser jp) throws IOException { 
    JsonFactory factory = jp.getCodec().getFactory(); 

    StringReader inputSource = (StringReader) jp.getInputSource(); 
    inputSource.reset(); 

    BufferedReader br = new BufferedReader(inputSource); 
    String source = br.readLine(); 

    return factory.createJsonParser(source); 
} 

과 :

private String findTokenText(JsonParser jp, String fieldName) throws IOException { 
    JsonParser parser = getResetParser(jp); 
    while (true) { 
     parser.nextToken(); 
     if (parser.hasCurrentToken()) { 
      switch (parser.getCurrentToken()) { 
       case END_ARRAY: 
       case END_OBJECT: 
       case NOT_AVAILABLE: 
       case START_ARRAY: 
       case START_OBJECT: 
       case VALUE_EMBEDDED_OBJECT: 
       case VALUE_FALSE: 
       case VALUE_NUMBER_FLOAT: 
       case VALUE_NUMBER_INT: 
       case VALUE_TRUE: 
        // do nothing 
        break; 
       case FIELD_NAME: 
        String currentName = parser.getCurrentName(); 
        if (fieldName.equals(currentName)) { 
         parser.nextToken(); 
         return parser.getText(); 
        } 
        break; 
      } 
     } else { 
      return null; 
     } 
    } 

내가 이해하지 못하는 것은 findTokenText 방법 내부 코드 jp.getText()inputSource.reset(); 수행에도 불구하고 (그냥 시도 이유 디버그 모드에서) 판독기가 다시 설정되지 않은 것처럼 "C"를 반환합니다. 아무도 설명 할 수 있습니까? 왜 이런 일이 발생합니까?

다른 변형은 맞춤 설정을 피하고 this 게시물의 제안을 사용하는 것입니다.

관련 문제