web-dev-qa-db-ja.com

@JsonPropertyプロパティはいつ使用され、何のために使用されますか?

このBeanの「状態」:

public class State {

    private boolean isSet;

    @JsonProperty("isSet")
    public boolean isSet() {
        return isSet;
    }

    @JsonProperty("isSet")
    public void setSet(boolean isSet) {
        this.isSet = isSet;
    }

}

ajaxの「success」コールバックを使用してネットワーク経由で送信されます。

        success : function(response) {  
            if(response.State.isSet){   
                alert('success called successfully)
            }

アノテーション@JsonPropertyはここで必要ですか?それを使用する利点は何ですか?私は私がこのアノテーションを少しも副作用を引き起こさずに取り除くことができると思います。

https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations でこのアノテーションについて読む使用する必要がありますか?

144
blue-sky

これは良い例です。 JSONはプロパティが大文字で始まる.Net環境から来ているので、変数の名前を変更するためにそれを使用します。

public class Parameter {
  @JsonProperty("Name")
  public String name;
  @JsonProperty("Value")
  public String value; 
}

これはJSONとの間で正しく解析されます。

"Parameter":{
  "Name":"Parameter-Name",
  "Value":"Parameter-Value"
}
186
OldCurmudgeon

OldCurmudgeonとStaxManはどちらも正しいと思いますが、ここでは簡単な例を挙げて1文の回答を示します。

@JsonProperty(name)は、JSONプロパティ名を注釈付きJavaフィールドの名前にマップするようにJackson ObjectMapperに指示します。

//example of json that is submitted 
"Car":{
  "Type":"Ferrari",
}

//where it gets mapped 
public static class Car {
  @JsonProperty("Type")
  public String type;
 }
33
grepit

jsonPropertyは、通常のシリアライゼーションおよびデシリアライゼーションとは別に、変数の取得メソッドおよび設定メソッドを指定するためにも使用されます。たとえば、次のようなペイロードがあるとします。

{
  "check": true
}

そしてDeserializerクラス:

public class Check {

  @JsonProperty("check")    // It is needed else Jackson will look got getCheck method and will fail
  private Boolean check;

  public Boolean isCheck() {
     return check;
  }
}

それからこの場合JsonPropertyアノテーションが必要です。ただし、そのクラスにもメソッドがある場合

public class Check {

  //@JsonProperty("check")    Not needed anymore
  private Boolean check;

  public Boolean getCheck() {
     return check;
  }
}

このドキュメントもご覧ください。 http://fasterxml.github.io/jackson-annotations/javadoc/2.3.0/com/fasterxml/jackson/annotation/JsonProperty.html

31
Richeek

注釈がないと、推論されたプロパティ名(JSONから突き合わせるため)は "set"になり、意図しているように "isSet"にはなりません。これは、Java Beans仕様に従って、「isXxx」および「setXxx」という形式のメソッドが、管理する論理プロパティー「xxx」があることを意味すると解釈されるためです。

12
StaxMan

ご存じのとおり、これはオブジェクトの直列化と脱塩についてのすべてです。オブジェクトがあるとします。

public class Parameter {
  public String _name;
  public String _value; 
}

このオブジェクトのシリアル化は次のとおりです。

{
  "_name": "...",
  "_value": "..."
}

変数の名前はデータを直列化するために直接使用されます。システム実装からシステムAPIを削除しようとしている場合、場合によっては、シリアル化/逆シリアル化で変数の名前を変更する必要があります。 @JsonPropertyは、シリアライザにオブジェクトのシリアル化方法を指示するメタデータです。それは慣れている:

  • 変数名
  • アクセス(読み取り、書き込み)
  • デフォルト値
  • 必須/オプション

例から:

public class Parameter {
  @JsonProperty(
        value="Name",
        required=true,
        defaultValue="No name",
        access= Access.READ_WRITE)
  public String _name;
  @JsonProperty(
        value="Value",
        required=true,
        defaultValue="Empty",
        access= Access.READ_WRITE)
  public String _value; 
}
3
Mostafa

JsonPropertyを追加することで、問題のクラスを認識していないプロパティ名の1つをJsonオブジェクトにシリアル化することを決定した場合の安全性も確保されます。プロパティ名を変更した場合、JsonPropertyはプロパティ名ではなくJsonオブジェクトで使用されるようにします。

3
arush436

他の答えに加えて、引数なしのコンストラクタを持たないクラスで@JsonPropertyアノテーションを使用する場合、@JsonCreatorアノテーションは本当に重要です。

public class ClassToSerialize {

    public enum MyEnum {
        FIRST,SECOND,THIRD
    }

    public String stringValue = "ABCD";
    public MyEnum myEnum;


    @JsonCreator
    public ClassToSerialize(MyEnum myEnum) {
        this.myEnum = myEnum;
    }

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();

        ClassToSerialize classToSerialize = new ClassToSerialize(MyEnum.FIRST);
        String jsonString = mapper.writeValueAsString(classToSerialize);
        System.out.println(jsonString);
        ClassToSerialize deserialized = mapper.readValue(jsonString, ClassToSerialize.class);
        System.out.println("StringValue: " + deserialized.stringValue);
        System.out.println("MyEnum: " + deserialized.myEnum);
    }
}

この例では、唯一のコンストラクタが@JsonCreatorとしてマークされているので、Jacksonはこのコンストラクタを使用してインスタンスを作成します。しかし、出力は以下のようになります。

シリアル化:{"stringValue": "ABCD"、 "myEnum": "FIRST"}

スレッド "main"での例外com.fasterxml.jackson.databind.exc.InvalidFormatException:文字列値 'stringValue'からClassToSerialize $ MyEnumのインスタンスを構築できません:宣言された列挙型のインスタンス名ではない値:[最初、2番目、3番目]

しかし、コンストラクタに@JsonPropertyアノテーションを追加した後は、

@JsonCreator
public ClassToSerialize(@JsonProperty("myEnum") MyEnum myEnum) {
    this.myEnum = myEnum;
}

逆シリアル化は成功します。

シリアル化された:{"myEnum": "FIRST"、 "stringValue": "ABCD"}

StringValue:ABCD

MyEnum:最初の

3
DVarga

上記のすべての答えに加えて、ドキュメントの以下の部分を忘れないでください

論理プロパティの「セッター」または「ゲッター」として非静的メソッドを定義するために使用できるマーカーアノテーション(署名に応じて)、または論理として使用される非静的オブジェクトフィールド(シリアル化、非シリアル化)プロパティ。

クラスに従来のnon-staticではないgetter or setterメソッドがある場合は、そのアノテーションを使用してgetter and setterのように動作させることができます。以下の例を参照してください

public class Testing {
    private Integer id;
    private String username;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getIdAndUsername() {
        return id + "." + username; 
    }

    public String concatenateIdAndUsername() {
        return id + "." + username; 
    }
}

上記のオブジェクトがシリアル化されると、応答には

  • getUsername()のユーザー名
  • getId()のID
  • idAndUsername from getIdAndUsername *

メソッドgetIdAndUsernamegetで始まるため、通常のゲッターとして扱われるため、なぜ@JsonIgnoreでアノテーションを付けることができるのでしょうか。

concatenateIdAndUsernameが返されないことに気付いたのは、名前がgetで始まっていないためであり、そのメソッドの結果を応答に含める場合は、@JsonProperty("...")を使用できます。上記の強調表示されたドキュメントで言及されているように、通常のgetter/setterとして扱われます。

0
Raf

JsonProperty javadocから、

論理プロパティの名前、つまりプロパティに使用するJSONオブジェクトのフィールド名を定義します。値が空の場合(デフォルト)、アノテーションが付けられているフィールドの名前を使用しようとします。

0
sc30