[java] 직렬화 중에는 @JsonIgnore 만 사용하고 역 직렬화는 사용하지 않습니다.

서버와주고받는 사용자 개체가 있습니다. 사용자 개체를 보낼 때 해시 된 암호를 클라이언트에 보내지 않습니다. 따라서 @JsonIgnorepassword 속성을 추가 했지만 암호가 deserialize되어 암호를 얻지 못한 경우 사용자를 등록하기가 어렵습니다.

@JsonIgnore직렬화 해제가 아닌 직렬화 에만 적용하려면 어떻게해야합니까? Spring JSONView를 사용하고 있으므로에 대한 많은 제어 권한이 없습니다 ObjectMapper.

내가 시도한 것 :

  1. @JsonIgnore속성에 추가
  2. @JsonIgnoregetter 메소드에만 추가


답변

정확히이 작업을 수행하는 방법은 사용중인 Jackson 버전에 따라 다릅니다. 이것은 버전 1.9 에서 변경 되었으므로 그 전에 @JsonIgnoregetter 에 추가하면 됩니다.

당신이 시도한 것 :

getter 메소드에서만 @JsonIgnore 추가

이를 수행 하고@JsonProperty JSON “암호”필드 이름에 대한 특정 주석을 오브젝트의 비밀번호에 대한 setter 메소드에 추가하십시오.

잭슨의 최신 버전은 추가 READ_ONLYWRITE_ONLY주석 인수 JsonProperty. 따라서 다음과 같은 작업을 수행 할 수도 있습니다.

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

문서는 여기 에서 찾을 수 있습니다 .


답변

이를 위해 두 가지 주석 만 있으면됩니다.

  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(final 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.


답변

필자의 경우 Spring MVC 컨트롤러에서 반환하는 객체를 Jackson (자동) 직렬화 해제하는 Jackson이 있습니다 (Spring 4.1.6에서 @RestController를 사용하고 있습니다). 그렇지 않으면 단순히 아무것도하지 않았기 때문에 com.fasterxml.jackson.annotation.JsonIgnore대신 대신 사용해야 org.codehaus.jackson.annotate.JsonIgnore했습니다.


답변

"user": {
        "firstName": "Musa",
        "lastName": "Aliyev",
        "email": "klaudi2012@gmail.com",
        "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
                }


답변

이것을 처리하는 또 다른 쉬운 방법은 인수를 사용하는 것입니다 allowSetters=true 은 주석에 입니다. 이렇게하면 암호를 dto로 역 직렬화 할 수 있지만 contains 객체를 사용하는 응답 본문으로 암호를 직렬화하지는 않습니다.

예:

@JsonIgnoreProperties(allowSetters = true, value = {"bar"})
class Pojo{
    String foo;
    String bar;
}

모두 foobar객체에 채워집니다,하지만 foo는이 응답 본문에 기록됩니다.


답변