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


325

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

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

내가 시도한 것 :

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

답변:


481

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

당신이 시도한 것 :

getter 메소드에서만 @JsonIgnore 추가

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

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

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

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


2
Jackson JSON 용 gist.github.com/thurloat/2510887 for deserialize 에서만 무시
Hadas

1
AFAIK 여전히 세터를 구현하고 주석을 달아야합니다. 나는 단지 직렬화를위한 게터를 원한다. 당신이 말하는 과도는 무엇입니까? 즉, JPA 주석 AFAIK입니다
매트 Broekhuis

3
또한 필드 자체에서 @JsonProperty를 제거해야합니다. 그렇지 않으면 getter / setter 주석이 무시됩니다.
Anton Soradoi

15
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
Mikhail Batcer

1
Jackson-Annotations 2.5에는 이후 기능이 없습니다. Jackson-Annotations 2.6.3 does
radiantRazor

98

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

  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
그것은 잭슨 2.6.4에서 나를 위해 일한 유일한 것입니다. @JsonProperty (access = Access.WRITE_ONLY)를 사용하기 위해 최선을 다했지만 작동하지 않았습니다.
cirovladimir

77

버전 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.


1
나는 왜 그렇게 공언이 적은지 이해하지 못합니다.이 문제를 해결하는 우아한 방법이며 매력처럼 작동합니다. getter, setter 및 field에 주석을 달 필요가 없습니다. 필드 만. 감사.
CROSP

이것은 버전 2.6부터 사용 가능합니다. fasterxml.github.io/jackson-annotations/javadoc/2.6/com/…
Daniel Beer

아마도 2.6 명 이상의 사용자에게 가장 적합한 답변 일 것입니다.
David Dossot

org.codehaus.jackson.annotate 가져 오기를 사용하고 있지 않은지 확인하십시오 . @DanielBeer의 솔루션은 Jackson 2.6.3에서 작동합니다. 잭슨이 업데이트되었으므로 이것이 정답입니다.
Kent Bull

13

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


1
이것은 @JsonIgnore가 Jackson에 의해 영예를 얻지 못한 이유의 근원을 찾는 데 실제로 도움이 된 매우 유용한 답변입니다 ... 감사합니다!
클린트 이스트우드

2
"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
                }

4
나중에 코드 작동 방식에 대한 간단한 설명을 제공하는 것이 도움이 될 수 있습니다.
KWILLIAMS

알았어 !! 여기서 무엇을 시도하고 있습니까? 더 많은 투표를 받고 있습니까? lol
Balaji Boggaram Ramanarayan

0

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

예:

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

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


그게 내 실수 였어 변경 사항을 살펴보면 Groovy에서 몇 년 동안 글을 쓰는 것으로 나타 났으며 Java 로의 번역은 약간 거칠 었습니다. 죄송합니다!
Dhandley
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.