2016-03-29 23 views
2

カスタムシリアライザを使用し、JsonInclude.Include.NON_DEFAULTの指定を受けたいとします。私がカスタムシリアライザを使用しない場合、それは賞賛されますが、カスタムシリアライザを使用するときはそうではありません。JsonInclude.Include.NON_DEFAULTがカスタムシリアライザで動作しない

これはJackson 2.2.2です。私は現在、ジャクソンの新しいバージョンに切り替えるオプションはありません。

import com.fasterxml.jackson.annotation.JsonGetter; 
import com.fasterxml.jackson.annotation.JsonInclude; 
import com.fasterxml.jackson.core.JsonGenerator; 
import com.fasterxml.jackson.databind.JsonSerializer; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.SerializerProvider; 
import com.fasterxml.jackson.databind.annotation.JsonSerialize; 

import java.io.IOException; 
import java.util.EnumSet; 
import java.util.Set; 
import java.util.stream.Collectors;  

public class JacksonSerialization 
{ 
    public static void main(String[] args) throws Exception { 
     ObjectMapper serializer = new ObjectMapper(); 

     Foo foo = new Foo(); 
     foo.setFlags(EnumSet.of(Flag.CC, Flag.BB)); 
     System.out.println(serializer.writeValueAsString(foo)); 

     foo = new Foo(); 
     System.out.println(serializer.writeValueAsString(foo)); 
    } 

    public static enum Flag 
    { 
     AA, 
     BB, 
     CC 
    } 

    @JsonInclude(JsonInclude.Include.NON_DEFAULT) 
    public static class Foo 
    { 
     private Set<Flag> flags; 

     public Foo() { 
      flags = EnumSet.of(Flag.AA); 
     } 

     @JsonGetter("f") 
     @JsonSerialize(using = FlagSetSerializer.class) 
     public Set<Flag> getFlags() { 
      return flags; 
     } 

     public void setFlags(Set<Flag> theFlags) { 
      flags = theFlags; 
     } 
    } 

    public static class FlagSetSerializer extends JsonSerializer<Set<Flag>> 
    { 
     @Override 
     public void serialize(Set<Flag> value, 
           JsonGenerator jsonGenerator, 
           SerializerProvider serializerProvider) throws IOException { 
      String csv = value.stream() 
        .map(Flag::toString) 
        .collect(Collectors.joining(",")); 
      jsonGenerator.writeString(csv); 
     } 
    } 
} 

そして、ここでは出力です:それはデフォルト値を持っている場合でも、fが連載されていることを

{"f":"BB,CC"} 
{"f":"AA"} 

注ここで

は、問題を示して簡単な例です。私は@JsonSerialize注釈をコメントアウトした場合、私は次のような出力が得られます。そして、

{"f":["BB","CC"]} 
{} 

fが正しくないを行い、シリアライズ得ます。もちろん、私が望む形式では物事はシリアル化されていません。

したがって、クラスの@JsonInclude注釈を尊重するカスタムシリアライザを取得するにはどうすればよいですか?

答えて

2

はおそらく言うdocumentation、あたりとしてpublic boolean isEmpty(SerializerProvider provider, T value)を実装する:

パブリックブールのisEmpty(SerializerProviderプロバイダー、T value)指定された直列化可能な値は を考えられているかどうかを確認するために呼び出さ

方法」空の値(空の 値のシリアライゼーションを抑制する目的で)。

デフォルトの実装では、NULL値のみが であるとみなされます。

https://github.com/FasterXML/jackson-databind/issues/730

を1として、トラブルの別の可能なソースは、あなたがおよそNON_EMPTYを話していることですが、あなたのコードは、NON_DEFAULTを使用しています。


はむしろあまりデバッガで掘ることはあなたの試験に合格すると思われる

@JsonSerialize(using = FlagSetSerializer.class, include = JsonSerialize.Inclusion.NON_DEFAULT)

を提案するために私をリード。

問題は、最初のプロパティに@JsonInclude属性を探している、JacksonAnnotationInspector#findSerializationInclusionであるように思われ、それはそれを見つけるのに失敗した時に、それは@JsonSerialize注釈を探します。 @JsonSerializeには廃止予定のincludeプロパティが含まれています。デフォルト値はALWAYSです。

私はあまりにも深く見ていないが、非難/リファクタがいくつかの機能を断ち切ったと思われる。 C'est la vie。

+0

「JsonSerializer」にそのシグネチャを持つメソッドはありません。また、 'NON_DEFAULT'については' NON_EMPTY'ではなく、尋ねています。 – QuantumMechanic

+0

NON_EMPTY対NON_DEFAULTのメモに感謝します。質問の誤りを修正するために質問を編集しました。 – QuantumMechanic

+0

どのバージョンのジャクソンを使用していますか?あなたは 'public boolean isEmpty(T value)'を見たいかもしれません。しかし、NON_DEFAULTの処理を実際に探している場合、これはすべて問題ではありません。 – ptomli

関連する問題