ジャクソン:フィールドのシリアル化を防ぐ方法


163

私はパスワードフィールドを持つエンティティクラスを持っています:

class User {
    private String password;

    //setter, getter..
}

シリアル化中にこのフィールドをスキップしたい。しかし、それでもデシリアライズできるはずです。これは、クライアントが新しいパスワードを送信できるようにするために必要ですが、現在のパスワードを読み取ることはできません。

ジャクソンでこれをどのように達成しますか?


1
シリアル化したくないが、逆シリアル化できるようにしたいですか?それは不可能だと私は言うでしょう。ボックスにcookieを入れないと、このボックスからcookieを取得できなくなります。
Alexis Dufrenoy

1
@Traroth:新しいクッキーを置くことができます。私は便利な注釈を探していますが、これは確かに手作業で行うことができます。
12

8
簡単なコメント:技術的には、セッターを使用して(プライベートのものでも自動検出されます)、アクセサーを省略(パブリックフィールドやゲッターなし)することは完全に可能です。@JsonIgnoregetter を追加することも可能ですが@JsonProperty、setter を追加することもできます。この場合、物事はシリアル化されませんが、逆シリアル化できます。
StaxMan

4
この質問の回答を受け入れてもらえますか?(他のカップルは数歳で、まだ受け入れられていません...レビューを検討してください!):)完全な開示-私はこれらの質問のいずれにも答えがありません。
Barett

回答:


187

としてマークでき@JsonIgnoreます。

1.9では、@JsonIgnoreゲッター@JsonProperty用、セッター用に追加して、逆シリアル化するがシリアル化しないようにすることができます。


6
@JsonIgnoreは逆シリアル化も防止します。一時的な場合-私はそれをチェックアウトします。
12

98
1.9では、@JsonIgnoreゲッター@JsonProperty用、セッター用に追加して、逆シリアル化するがシリアル化しないようにすることができます。
StaxMan、2012

StaxManのコメントが答えになるはずですよね。なぜそれがまだコメントなのですか...!..?
サラバナバラギラマチャンドラン

一時的なものは私にはうまくいかないようです、私はフィールドを「一時的」にマークしました。
rohith 2016

この回答は以前にtransient(のようにprivate transient String password;)を使用することを提案しましたが、MapperFeature.PROPAGATE_TRANSIENT_MARKERが有効になっていない限り、パブリックゲッターの一時フィールドは無視されます。
トム

96

StaxManが言ったことを説明すると、これは私にとってはうまくいきます

private String password;

@JsonIgnore
public String getPassword() {
    return password;
}

@JsonProperty
public void setPassword(String password) {
    this.password = password;
}

12
どのJson依存関係を使用していますか?これはcom.fasterxml.jacksonでは機能しません
Alexander Burakevych 2014

3
ありがとう!@JsonIgnore現場では必要ないようです。
Ferran Maylinch 2014

com.fasterxml.jackson.annotation.JsonIgnore from jackson-annotations- <version> .jar
mvmn

私はこれを試しましたが、うまくいきません。私はv2.8を使用しています。何か助け?
Maz

36

簡単な方法は、ゲッターとセッターに注釈を付けることです。

元の例は、プレーンテキストのパスワードを除外するように変更されていますが、暗号化されたテキストとしてパスワードフィールドを返すだけの新しいメソッドに注釈を付けています。

class User {

    private String password;

    public void setPassword(String password) {
        this.password = password;
    }

    @JsonIgnore
    public String getPassword() {
        return password;
    }

    @JsonProperty("password")
    public String getEncryptedPassword() {
        // encryption logic
    }
}

21

以降ではジャクソン2.6、プロパティが読み取りまたは書き込み専用としてマークすることができます。両方のアクセサーの注釈をハッキングするよりも簡単で、すべての情報を1か所に保持します。

public class User {
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String password;
}

これは素晴らしいソリューションであり、シンプルで機能します。ありがとう。
dhqvinh

17

の他に@JsonIgnore、他にもいくつかの可能性があります。

  • JSONビューを使用してフィールドを条件付きでフィルターで除外します(デフォルトでは、非直列化には使用されません。2.0では使用可能になりますが、直列化、非直列化で別のビューを使用できます)
  • @JsonIgnoreProperties クラスで役立つかもしれません

10

transient私のためのソリューションです。ありがとう!これはJavaのネイティブであり、フレームワーク固有の別のアノテーションを追加する必要がありません。


2
たとえば、属性が本当に一時的で、ORMが関与していない場合に機能します。たとえば、@ JsonIgnoreは私の場合より興味深いことがわかりましたが、私はジャクソンにロックされますが、それは良いトレードオフです
Joao Pereira

3
独自の注釈を作成し、JsonIgnoreとJacksonAnnotationsInsideで注釈を付ける場合は、jacksonにロックする必要はありません。そうすれば、シリアライザを変更した場合でも、自分の注釈を変更するだけで済みます。
DavidA 2014年

4

パスワードにパブリックゲッターメソッドが必要な理由を尋ねる必要があります。Hibernate、またはその他のORMフレームワークは、プライベートゲッターメソッドを使用します。パスワードが正しいかどうかを確認するには、

public boolean checkPassword(String password){
  return this.password.equals(anyHashingMethod(password));
}

私は実際にこれがソリューションについて考える最良の方法だと思います。必要なものを非公開にして、オブジェクト自体から制御する方が理にかなっています。
arcynum 2017年

2

ジャクソンには、直列化および直列化復元時にフィールドをフィルタリングするのに役立つSimpleBeanPropertyFilterという名前のクラスがあります。グローバルではありません。それがあなたの望んだことだと思います。

@JsonFilter("custom_serializer")
class User {
    private String password;

    //setter, getter..
}

次に、コードで:

String[] fieldsToSkip = new String[] { "password" };

ObjectMapper mapper = new ObjectMapper();

final SimpleFilterProvider filter = new SimpleFilterProvider();
filter.addFilter("custom_serializer",
            SimpleBeanPropertyFilter.serializeAllExcept(fieldsToSkip));

mapper.setFilters(filter);

String jsonStr = mapper.writeValueAsString(currentUser);

これにより、passwordフィールドがシリアル化されなくなります。また、passwordフィールドをそのまま逆シリアル化することもできます。ObjectMapperオブジェクトにフィルターが適用されていないことを確認してください。

ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(yourJsonStr, User.class);    // user object does have non-null password field

0

変数を

@JsonIgnore

これにより、jsonシリアライザーによって変数をスキップできます

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