2017-11-13 15 views
1

Swagger 정의에서 클래스를 생성했습니다. 하나의 필드가 공통적으로 op 인 4 가지 클래스가 있습니다 (클래스 계층 구조가 없으며 필드는 각 클래스에서 복제됩니다).JSON 데이터의 스트림을 객체로 읽는 Jackson과 생성 된 클래스 작업

op 필드의 값에 따라 JSON 데이터 스트림을 4 개의 다른 클래스 중 하나로 역 직렬화하려고합니다. 예를 들어

:

나는이 잭슨을 사용할
{"op": "typeA", ...} -> generates TypeA 
{"op": "typeB", ...} -> generates TypeB 

. 문제는 내가 가진 모든 예제는 원래 클래스를 수정하여 클래스 계층 구조로 문제를 해결할 수 있다고 가정한다는 것입니다. 그러나 내 질문에 어떻게 원래 클래스를 수정하지 않고이 문제를 해결할 수 있습니다?

는 원래 예는 계층 구조를 가정하고 다음과 같이 수행됩니다

@JsonTypeInfo(
     use = JsonTypeInfo.Id.NAME, 
     include = JsonTypeInfo.As.PROPERTY, 
     property = "op", 
     visible = true) 
@JsonSubTypes({ 
     @JsonSubTypes.Type(value = ConnectionMessage.class, name = "connection"), 
     @JsonSubTypes.Type(value = StatusMessage.class, name = "status"), 
     @JsonSubTypes.Type(value = MarketChangeMessage.class, name = "mcm"), 
     @JsonSubTypes.Type(value = OrderChangeMessage.class, name = "ocm"), 
}) 
public interface MixInResponseMessage { 

} 
+0

위의 내용을 전제로하기 때문에이 답변은 완전하지 않습니다. 그러나 믹스 인을 사용하여 가능한 경우 아이디어를 얻을 수 있어야합니다. 다음은 믹스 라인을 사용하여 부모 추상 클래스를 타겟팅하는 예입니다. https://github.com/Flaw101/springbootmixin –

답변

1

이는 스위치를 사용자 정의 디시리얼라이저 수행 할 수 있습니다 - "OP"의 값에 따라 올바른 유형을 분석 할 경우 문 필드 : ObjectMapper 필드가 필요한 형식의 개체에 TreeNode을 변환하는 데 사용되는 방법

class OpDeserializer extends JsonDeserializer { 
    private final ObjectMapper mapper = new ObjectMapper(); 

    @Override 
    public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { 
     final JsonNode node = jsonParser.readValueAsTree(); 
     final String op = node.get("op").asText(); 
     switch (op) { 
      case "typeA": return mapper.treeToValue(node, TypeA.class); 
      case "typeB": return mapper.treeToValue(node, TypeB.class); 
      default: return mapper.treeToValue(node, Object.class); 
     } 
    } 
} 

참고.

TypeA, TypeB 등은 Object을 제외한 다른 공통 상위를 가질 필요가 없습니다.

"op" 필드가있는 각 JSON 요소에 사용 된대로이 디시리얼라이저를 지정해야합니다.

class Ops { 
    @JsonDeserialize(contentUsing = OpDeserializer.class) 
    Object[] ops; 
}