2017-06-15 14 views
1

カスタムシリアル化を使用すると、プロパティ名がフィールド名と等しくない場合に予期しない結果が発生する可能性があります。 なぜフィールドが2回シリアル化されるのですか?プロパティの名前がフィールド名と等しくない場合、Jacksonカスタムシリアライザはフィールドを2回シリアル化します

私のコードサンプル:

class Mode { 
    @JsonProperty("mode") 
    @JsonSerialize(using = ModeSerializer.class) 
    private boolean isPublic; 

    public Mode(boolean isPublic) { 
     this.isPublic = isPublic; 
    } 

    public boolean isPublic() { 
     return isPublic; 
    } 
} 

ここに私のカスタムフィールド・シリアライザ:

class ModeSerializer extends JsonSerializer<Boolean> { 

     @Override 
     public void serialize(Boolean value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { 
      String out = "private"; 
      if (value) { 
       out = "public"; 
      } 
      gen.writeString(out); 
     } 
    } 

そして、ここでのテスト:

public class Test { 
    public static void main(String[] args) throws IOException { 
     ObjectMapper mapper = new ObjectMapper(); 
     Mode mode = new Mode(true); 
     String toJson = mapper.writeValueAsString(mode); 
     System.out.println(toJson); 
    } 
} 

そして、私が受け取る結果:

{"public":true,"mode":"public"} 

私は間違っていますか?

答えて

0

ジャクソンは、ゲッターメソッドのjava beans規則に従います。

これらによると、isPublicは、ModeisPublicフィールドとは異なるpublicというブール値プロパティのゲッターです。ジャクソンはそれを"public":trueとしてシリアル化します。

さらに、指定した名前がmodeのフィールドでJacksonがシリアル化する@JsonPropertyを指定します。

@JsonDeserializeフィールドの注釈は、フィールドの名前がゲッターメソッドによって暗示されたものと一致した場合、ゲッターを無視させる原因になります。 isPublicという名前のブール型フィールドに対応するgetterメソッドはisIsPublic()

あなたが上記には影響を与えませんmodeのJSONフィールド名を指定していることだろう。

0

詳細な回答ありがとうございます。
getter Publicを分離する必要があります。このメソッドの名前を変更するだけでなく、@ JsonIgnoreアノテーションをメソッドに使用することもできます。 このように:

class Mode { 
    @JsonProperty("mode") 
    @JsonSerialize(using = ModeSerializer.class) 
    private boolean isPublic; 

    public Mode(boolean isPublic) { 
     this.isPublic = isPublic; 
    } 

    @JsonIgnore 
    public boolean isPublic() { 
     return isPublic; 
    } 
} 

これは私のために働いています。

関連する問題