2013-03-07 2 views
1

JSON에서 이와 같이 정의 된 사람들의 컬렉션이 있다고 가정합니다.잭슨 역 직렬화 - 여러 필드 집합

{ 
     "NOM": "Doe", 
     "PRENOM": "John", 
     "EMAIL": "[email protected]", 
     "VILLE": "Somewhere", 
     "LIKE1": "Lolcats", 
     "LIKE2": "Loldogs", 
     "LIKE3": "Lolwut", 
     "HATE1": "Bad stuff", 
     "HATE2": "Bad bad stuff" 
} 

그것은 사람의 속성으로 설정 집계하고 * LIKE 변환 좋아요 표시의 모음으로 * 필드를 미워하는 JsonDeserializer을 쓸 수 있습니까? (. 단지 LIKE1, LIKE2, LIKE3, HATE1, HATE2 있다는 것을 참고)

를 최종 결과의 속성을 볼 수있는 작품 같은 :

public class Person { 
    private final String lastName; 
    private final String firstName; 
    private final String email; 
    private final String town; 
    private final Collection<Liking> likings; 
    // c-tor, getters 
} 

나는 이미 같은 주어진 역 직렬화 할 수있는 논리를했습니다 */HATE * 속성을 Liking 객체에 추가하지만 Person liking 속성에 집계하고 추가하는 것을 이해하지 못합니다.

미리 Thx!

답변

1

이 문제를 직접 해결하십시오.

class PersonDeserializer extends JsonDeserializer<Person> { 

    @Override 
    public Person deserialize(final JsonParser parser, 
      final DeserializationContext content) throws IOException, 
      JsonProcessingException { 

     final ObjectCodec codec = parser.getCodec(); 
     final JsonNode node = codec.readTree(parser); 

     final Person person = new Person(); 
     final Iterator<String> fieldNameIter = node.getFieldNames(); 
     while (fieldNameIter.hasNext()) { 
      final String fieldName = fieldNameIter.next(); 
      if (fieldName.equalsIgnoreCase("EMAIL")) { 
       person.setEmail(node.get(fieldName).getTextValue()); 
      } else if (fieldName.equalsIgnoreCase("NOM")) { 
       person.setFirstName(node.get(fieldName).getTextValue()); 
      } else if (fieldName.equalsIgnoreCase("PRENOM")) { 
       person.setLastName(node.get(fieldName).getTextValue()); 
      } else if (fieldName.equalsIgnoreCase("VILLE")) { 
       person.setTown(node.get(fieldName).getTextValue()); 
      } else if (fieldName.startsWith("LIKE")) { 
       person.addLike(Liking.LikingType.LIKE, node.get(fieldName) 
         .getTextValue()); 
      } else if (fieldName.startsWith("HATE")) { 
       person.addLike(Liking.LikingType.HATE, node.get(fieldName) 
         .getTextValue()); 
      } 
     } 

     return person; 
    } 
} 

는 그것은 Liking 이와 유사한 개체를 가정 :하지만, 여기 당신이 찾고있는 무엇을 거의하지 샘플 사용자 정의 디시리얼라이저이다

public class Liking { 
    public static enum LikingType { 
     LIKE, HATE; 
    } 

    private LikingType type; 

    private String value; 

    // Constructors, getters/setters 
} 

그리고 당신의 Person 객체에 약간의 변화는 나는 당신이 알아낼 수 있다고 생각합니다. 같은 사용자 정의 형식으로 객체를 JSON으로 serialize하려면 해당 JsonSerializer을 작성해야합니다.

강건하지는 않은 또 다른 옵션은 좋아요와 싫어요를 그대로 그대로 저장하기 위해지도를 사용하는 것입니다. 이 솔루션은 좋아요/싫어요에 대한 명시적인 매핑을 생략하고 @JsonAny 주석을 사용하여 캡처합니다. 이 방식에서는 Person 객체는 다음과 같이 보일 것이다 :

public class Person { 
    private String lastName; 
    private String firstName; 
    private String email; 
    private String town; 
    @JsonAny 
    private Map<String, Object> otherProperties; 

    // Constructors, getters/setters 
} 

키 - 값 쌍으로, 해시 맵에 모든 알 수없는 속성을 배치합니다 Person의 수정 된 버전으로 JSON 직렬화를 해제.

+0

나는 Liking 클래스를위한 deserializer를 작성했다. Thx for sharing;) – Rolf

+0

No prob, enjoy! – Perception

1

나는 당신이 그것을 당신이하려는 방법을 수행 할 수 없습니다 확신하는 방법을 다음과 같이 그 일에 대해 : 당신이 과정을 시작했다 일부 코드가 있다면 그것은 좋은했을

{ 
     "NOM": "Doe", 
     "PRENOM": "John", 
     "EMAIL": "[email protected]", 
     "VILLE": "Somewhere", 
     "likings": ["Lolcats", "Loldogs", "LIKE3": "Lolwut", "Bad stuff", "Bad bad stuff" ] 
} 
+0

나는이 일을 끝낼 것이라고 생각한다. – Rolf