2016-11-03 3 views
3

필자에게는 Optional 필드가있는 Java 클래스가 있습니다. Jackson 2.8.3 (Spring 웹 4.3.3에서 호출)을 사용하여 클래스를 JSON에 직렬화했다.Jackson 직렬화 중에 Optional.empty 필드를 건너 뛰는 방법은 무엇입니까?

Optional이 비어있는 경우 serializer에서 필드를 건너 뛰고 포함 된 문자열이 있으면 serialize하는 것이 좋습니다. 나는 두 개체의 목록을 찾고 있어요 결과의 예 : 여기

[ 
    { 
     "id": 1, 
     "foo": "bar" 
    }, 
    { 
     "id": 2, 
    } 
] 

옵션 푸는 내가 무엇을 얻을 것은, 2

대신 ID를 가진 개체에 대한 비어 :

[ 
    { 
     "id": 1, 
     "foo": { 
      "present": true 
     } 
    }, 
    { 
     "id": 2, 
     "foo": { 
      "present": false 
     } 
    } 
] 

이것은 내가

@JsonInclude(JsonInclude.Include.NON_ABSENT) 
public Optional<String> getFoo() { ... 

같은 클래스에서 "바"필드에 주석을해도 결과는 워싱턴이 있습니다 y 잭슨 주석 또는 사용자 지정 직렬 변환기를 사용하여 첫 번째 목록과 같은 결과를 얻을 수 있습니까?

+1

'선택적'을 빈 필드로 사용하는 것은 일반적으로 Bad Idea ™입니다. – biziclop

+0

왜 이것이 문제가 있다고 생각합니까? –

+0

그런 종류의 사용을 위해 설계되지 않았습니다. 매우 미묘한 의미 론적 차이이지만 필드의 경우 'null'은 다른 값으로 간주됩니다. 라이브러리의 API에서 메소드를 설계하는 경우, 값을 리턴하지 않을 수도 있으므로 '선택 사항'을 사용하는 것이 중요 할 수 있습니다. 자세한 내용은 [여기] (http://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type/26328555#26328555) – biziclop

답변

1

필요에 따라 JsonSerializer을 사용하십시오.

이 (반 의사)와 같은

뭔가 :

public class MySer extends JsonSerializer<Opional<?>> { 

     @Override 
     public void serialize(Optional<?> optString, JsonGenerator generator, SerializerProvider provider) 
              throws IOException, JsonProcessingException { 
     //Check Optional here...   
     generator.writeString(/* DO SOMETHING HERE WHATEVER */); 
    } 

// 그런 다음 모델 :

public class ClassWhatever {   
    @JsonSerialize(using = MySer .class) 
    public Optional<String> getFoo() { ... 
} 

가 @JsonSerialize으로 모든 분야에 주석을 방지하기 위해 당신이 객체에 사용자 정의 시리얼을 등록 할 수 있습니다 매퍼 사용

ObjectMapper mapper = new ObjectMapper(); 
SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null)); 
testModule.addSerializer(new MyCustomSerializer()); // assuming serializer declares correct class to bind to 
mapper.registerModule(testModule); 

또한 제공된 솔루션은 직렬화에서만 작동합니다. deserializer를 작성하지 않으면 deserialization이 실패합니다. 그런 다음 모든 필드에 @JsonDeserializ e로 주석을 달거나 사용자 정의 디시리얼라이저를 등록해야합니다.

+0

com.fasterxml.jackson.datatype : jackson-datatype-jdk8 더 나은 옵션입니다. 이러한 사용자 지정 솔루션을 사용하면 모든 필드에 주석을 달 필요가 있습니다. 또한 deserialization은 사용자 지정 디시리얼라이저를 작성하고 @JsonDeserialize로 모든 필드에 주석을다는 경우에만 작동합니다. –

+0

@ BartoszBilicki 물론 동의합니다. 두 가지 모두 효과가 있지만 추천은 좋습니다. – Mechkov

8

사용자 지정 serializer를 쓸 필요가 없습니다. 수업에 @JsonInclude(JsonInclude.Include.NON_NULL)으로 주석을 답니다. NON_ABSENTNON_EMPTY도 정상적으로 작동합니다.

종속성으로 com.fasterxml.jackson.datatype:jackson-datatype-jdk8도 포함시켜야합니다.

+0

감사합니다. com.fasterxml.jackson.datatype에 대한 종속성을 포함합니다. jackson-datatype-jdk8이 트릭을 수행했습니다. –

+0

@JsonInclude (JsonInclude.Include.NON_ABSENT)로 충분합니다. – GKVM

관련 문제