web-dev-qa-db-ja.com

直列化中に@JsonIgnoreのみを使用し、直列化復元は使用しない

サーバーとの間で送受信されるユーザーオブジェクトがあります。ユーザーオブジェクトを送信するとき、ハッシュされたパスワードをクライアントに送信したくありません。そのため、passwordプロパティに@JsonIgnoreを追加しましたが、これによってパスワードへの逆シリアル化もブロックされるため、ユーザーがパスワードを取得していないときにサインアップするのが難しくなります。

どのようにして@JsonIgnoreをシリアル化に適用し、逆シリアル化には適用できないのですか?私はSpring JSONViewを使っているのでObjectMapperを制御することはできません。

私が試したこと:

  1. プロパティに@JsonIgnoreを追加します
  2. Getterメソッドにのみ@JsonIgnoreを追加する
265
chubbsondubs

これを行う方法は、使用しているJacksonのバージョンによって異なります。これはバージョン 1.9 を中心に変更されましたが、それ以前は、getterに@JsonIgnoreを追加することでこれを実行できました。

あなたが試したもの:

取得メソッドにのみ@JsonIgnoreを追加します。

そして これを実行して、JSONの "password"フィールド名の特定の@JsonPropertyアノテーションをオブジェクトのパスワードの設定メソッドに追加します。

Jacksonの最近のバージョンでは、JsonPropertyREAD_ONLYおよびWRITE_ONLYアノテーション引数を追加しました。だからあなたはまた、のようなことをすることができます

@JsonProperty(access = Access.WRITE_ONLY)
private String password;

ドキュメントは ここ にあります。

391
pb2q

これを実現するために必要なのは、2つのアノテーションだけです。

  1. @JsonIgnore
  2. @JsonProperty

クラスメンバーとそのゲッターに@JsonIgnoreを使用してください。セッターに@JsonPropertyを使用してください。

サンプルイラストはこれをするのを助けるでしょう:

class User{

// More fields here
 @JsonIgnore
 private String password;

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

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

バージョン2.6以降:もっと直感的な方法はフィールド上でcom.fasterxml.jackson.annotation.JsonPropertyアノテーションを使うことです:

@JsonProperty(access = Access.WRITE_ONLY)
private String myField;

ゲッターが存在していても、フィールド値は直列化から除外されます。

JavaDocは言います:

/**
 * Access setting that means that the property may only be written (set)
 * for deserialization,
 * but will not be read (get) on serialization, that is, the value of the property
 * is not included in serialization.
 */
WRITE_ONLY

逆の方法でそれが必要な場合は、Access.READ_ONLYを使用してください。

66
Daniel Beer

私の場合は、Spring MVCコントローラから返されたオブジェクトをJacksonに自動的にシリアライズ/デシリアライズさせています(私はSpring 4.1.6で@RestControllerを使用しています)。私はcom.fasterxml.jackson.annotation.JsonIgnoreの代わりにorg.codehaus.jackson.annotate.JsonIgnoreを使わなければなりませんでした、そうでなければそれは単に何もしませんでした。

10
Alex Beardsley
"user": {
        "firstName": "Musa",
        "lastName": "Aliyev",
        "email": "[email protected]",
        "passwordIn": "98989898", (or encoded version in front if we not using https)
        "country": "Azeribaijan",
        "phone": "+994707702747"
    }

@CrossOrigin(methods=RequestMethod.POST)
@RequestMapping("/public/register")
public @ResponseBody MsgKit registerNewUsert(@RequestBody User u){

        root.registerUser(u);

    return new MsgKit("registered");
}  

@Service
@Transactional
public class RootBsn {

    @Autowired UserRepository userRepo;

    public void registerUser(User u) throws Exception{

        u.setPassword(u.getPasswordIn());
        //Generate some salt and  setPassword (encoded -  salt+password)
        User u=userRepo.save(u);

        System.out.println("Registration information saved");
    }

}

    @Entity        
@JsonIgnoreProperties({"recordDate","modificationDate","status","createdBy","modifiedBy","salt","password"})
                    public class User implements Serializable {
                        private static final long serialVersionUID = 1L;

                        @Id
                        @GeneratedValue(strategy=GenerationType.AUTO)
                        private Long id;

                        private String country;

                        @Column(name="CREATED_BY")
                        private String createdBy;

                        private String email;

                        @Column(name="FIRST_NAME")
                        private String firstName;

                        @Column(name="LAST_LOGIN_DATE")
                        private Timestamp lastLoginDate;

                        @Column(name="LAST_NAME")
                        private String lastName;

                        @Column(name="MODIFICATION_DATE")
                        private Timestamp modificationDate;

                        @Column(name="MODIFIED_BY")
                        private String modifiedBy;

                        private String password;

                        @Transient
                        private String passwordIn;

                        private String phone;

                        @Column(name="RECORD_DATE")
                        private Timestamp recordDate;

                        private String salt;

                        private String status;

                        @Column(name="USER_STATUS")
                        private String userStatus;

                        public User() {
                        }
                // getters and setters
                }
2
Musa