2016-11-03 9 views
3

私はオプションのフィールドを持つJavaクラスを持っています。 JSONをJackson 2.8.3(Spring Web 4.3.3から呼び出されました)を使用してクラスをシリアライズしています。ジャクソンのシリアル化中にOptional.emptyフィールドをスキップする方法は?

オプションが空の場合はシリアライザにフィールドをスキップさせ、含まれている場合はシリアル化したいと考えています。私は2つのオブジェクトのリストを探していた結果の例:ここでは

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

オプションfooが、私が取得することで、2

代わりにidを持つオブジェクトの空です:

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

これは私が

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

のようにクラスに「バー」フィールドに注釈を付けても、結果がどのwaがありますですy Jacksonの注釈やカスタムシリアライザを使用した最初のリストのような結果を得ることができますか?

+1

「オプション」をBeanのフィールドとして使用することは、一般的にBad Idea™です。 – biziclop

+0

なぜそれは問題であると考えられますか? –

+0

このような用途には設計されていませんでした。これは非常に微妙な意味の違いですが、フィールドの場合、 'null'は単なる別の値とみなされます。一方、ライブラリのAPIでメソッドを設計している場合は、値を返さないことがあるため、 'Optional'を使用することを強調したいかもしれません。もっと見る[ここ](http://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type/26328555#26328555) – biziclop

答えて

1

お客様のニーズに応じてJsonSerializerを使用してください。あなたがオブジェクトにカスタム・シリアライザを登録することが@JsonSerializeですべてのフィールドに注釈を付ける避けるため

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

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 */); 
    } 

//次に、あなたのモデルで:この(半擬似)のような

何かマッパー使用

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); 

また、指定されたソリューションはシリアル化のためにのみ動作します。独自のデシリアライザを作成しない限り、逆シリアル化は失敗します。次に、すべてのフィールドに@JsonDeserializ eという注釈を付けるか、カスタムデシリアライザを登録する必要があります。

+0

com.fasterxml.jackson.datatype:jackson-datatype-jdk8より良い選択肢です。そのようなカスタムソリューションでは、すべてのフィールドに注釈を付ける必要があります。また、デシリアライゼーションは、カスタムデシリアライザを作成し、すべてのフィールドに@JsonDeserializeというアノテーションを付けない限り、動作しません。 –

+0

@BartoszBilicki確かに、そこにあなたと同意します。どちらもうまくいくが、あなたのお勧めは良い。 – Mechkov

8

カスタムシリアライザを書く必要はありません。あなたのクラスに@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

関連する問題