2013-05-08 1 views
3

(면책 조항 :.. 극단적 인 단순화 실제 시나리오는 훨씬 더 복잡하다)잭슨 : 인터페이스로 열거 일렬

내가 두 시스템, 생산자와 소비자를 말한다. 그들의 코드 옆으로 단일 공유 인터페이스에서 완전히 독립적 인 :

public interface Thing { 
    String getName(); 
    String getDescription(); 
    int getPrice(); 
} 

아이디어는 생산자가 데이터의 무리를 생성하고 HTTP를 통해 JSON으로 전송하는 것입니다. 제작자는 데이터 생성 과정에서 필요한 메타 데이터 및 항목의 추가 조각으로 각각의 구현의 무리가 있습니다.

매우 얇은 레이어를 제외하고 Producer가 Jackson/serialization에 대한 지식을 갖고 있으면 바람직하지 않으므로 직렬화 속성은 Thing 구현에서 제외되어야합니다. 구현의 양은 앞으로 증가 할 가능성이 매우 높기 때문에 모든 믹스 인을 신속하게 유지할 수 없게됩니다. Thing 인터페이스 자체에 주석을 적용하는 것으로 충분하다고 여겨졌습니다.

첫 번째 간단한 접근 방식은 인터페이스에서 @JsonSerialize 주석이었습니다. 처음 엔 그럴 수밖에 없었지만 문제가 발생했습니다. Thing의 구현 중 일부는 열거 형 (enum)이므로 Jackson은 인터페이스에 정의 된 필드 대신 단순히 이름으로 직렬화합니다. 그것은 또한 특정 구현를 직렬화하기 시작했다대로 너무 잘했다,

@JsonFormat(shape= JsonFormat.Shape.OBJECT) 

가 실제로 이름 대신 필드를 직렬화하여 문제를 해결 않았지만 :

일부 인터넷 검색은 다음과 같은 주석을 밝혀 Thing 인터페이스에 정의되지 않은 public 필드는 정보 유출뿐만 아니라 알 수없는 항목이 포함 된 데이터로 인해 Consumer에서 deserialization에 실패했습니다.

더 많은 검색 결과가 나오지 않았기 때문에 내가 생각할 수있는 유일한 해결책은 모든 필드를 무시할 수있는 것으로 표시하는 것입니다. 이전에 언급 한 이유로 인해 매우 바람직하지 않습니다.

인터페이스 자체와 주석을 변경하여 클래스와 열거 형 모두에 대해 해당 필드가 정확하게 직렬화되도록하는 방법이 있습니까?

+0

enum을 사용하지 않고 대신 일반 클래스를 사용할 수 있습니까? –

+0

@reverse_engineer 이론적으로 그렇습니다.그러나 일부 구현을 열거 형으로 사용하면 Producer를 간소화 할 수있는 여러 가지 이유가 있습니다. 클래스를 클래스로 대체하는 것은 실제로 옵션이 아닙니다. – Smallhacker

+0

아마 @JsonFormat이 필요 하겠지만, https://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/ObjectMapper.html#writerFor(java.lang.Class) 직렬화의 타입을 지시하는 또 다른 방법입니다. 예를 들어, mapper.writerFor (Thing.class) .writeValue ... – Dan

답변

1

나는 Jackson과 함께 일할 때이 문제가 있습니다. 직렬화 복원 중에 Jackson이 다형 참조 유형을 찾을 수 없기 때문에 직렬화가 실패합니다.

@JsonTypeInfo로 인터페이스에 주석을 추가해야합니다. 같은

뭔가 :

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "class") 

귀하의 질문에 코드의 많은 따라서이 답변이 없습니다.

+0

이 경우 다형성은 문제가되지 않습니다. 소비자는 클래스가 원래 무엇인지 신경 쓰지 않습니다. Thing 인터페이스를 구현하는 일반적인 bean-like 클래스로 데이터를 deserialize합니다. 문제는 너무 많이 직렬화하지 않는 것입니다. – Smallhacker

0

일반적으로 당신과 함께 특정 유형의 사용을 강제 할 수 있어야한다 : @JsonDeserialize와 유사하게

@JsonSerialize(as=Thing.class) 

하고 있습니다. 열거 형과 함께 작동하지 않습니까?