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


183

この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でこの注釈について読んでいますこれをいつ使用する必要があるかわかりませんか?


回答:


238

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

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

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

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

1
Stringメンバー変数の名前を正しい大文字小文字に変更できないので、パブリックString名; パブリック文字列名になります。?
青空

14
はい、可能ですが、Java環境ではコーディング標準に適合しません。実際のコーディングの問題は、私のペダントリーについてですが、@JsonPropertyアノテーションの実際の使用例としては優れていますが、シンプルです。
OldCurmudgeon 2012

この注釈をタイプのメンバーに使用できますDoubleか?String型がJSONがサポートする型である必要があるのか​​と思っているだけですか?それはどんなタイプでしょうか?@OldCurmudgeon
Dreamer

3
@Dreamerはい。タイプは無関係です。これは名前にのみ影響します
OldCurmudgeon 2017

1
@Pavan-それはネーミングとは何の関係もありません。セッターを調べたほうがいいと思います。
OldCurmudgeon 2017

44

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

クラス名はJSONのルート要素と同じである必要がありますか?これは私のために働いていません。
Pavan 2017

39

JsonPropertyは、通常のシリアル化および逆シリアル化とは別に、変数のゲッターメソッドとセッターメソッドを指定するためにも使用されます。たとえば、次のようなペイロードがあるとします。

{
  "check": true
}

そしてデシリアライザクラス:

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


15

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


1
これは、質問で指定された特定のケースに対する正解です
Andrew Spencer

6

ご存知のように、これはオブジェクトのシリアル化と脱塩に関するすべてです。オブジェクトがあるとしましょう:

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

6

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


3

他の回答に加えて、引数のないコンストラクタを持たないクラスでアノテーション@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ため、ジャクソンはこのコンストラクターを使用してインスタンスを作成します。しかし、出力は次のようになります。

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

スレッド "main"の例外com.fasterxml.jackson.databind.exc.InvalidFormatException:ClassToSerialize $ MyEnumのインスタンスを文字列値 'stringValue'から構築できません :値が宣言されたEnumインスタンス名の1つではありません:[FIRST、SECOND、THIRD]

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

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

逆シリアル化は成功しました:

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

StringValue:ABCD

MyEnum:FIRST


2

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

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

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()
  • からのID getId()
  • getIdAndUsername* からのidAndUsername

メソッドgetIdAndUsernameはそれから始まるgetので、それは通常のゲッターとして扱われるので、なぜそのように注釈することができ@JsonIgnoreます

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


0

JsonProperty javadocから、

論理プロパティの名前、つまりプロパティに使用するJSONオブジェクトフィールド名を定義します。値が空の文字列(デフォルト)の場合、注釈付きのフィールドの名前を使用しようとします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.