Serileştirme sırasında sadece @JsonIgnore kullanılıyor, ancak serileştirme kullanılmıyor


325

Sunucuya ve sunucudan gönderilen bir kullanıcı nesnesi var. Kullanıcı nesnesini gönderdiğimde, karma şifreyi istemciye göndermek istemiyorum. Bu nedenle, @JsonIgnorepassword özelliğine ekledim , ancak bu aynı zamanda parolayı serileştirmesini de engelliyor ve bu da kullanıcıların bir parola olmadığında kaydolmasını zorlaştırıyor.

@JsonIgnoreSerileştirmeye değil, sadece serileştirmeye nasıl başvurabilirim? Spring JSONView kullanıyorum, bu yüzden üzerinde bir ton kontrolüm yok ObjectMapper.

Denediğim şeyler:

  1. Ekle @JsonIgnoreözelliğine
  2. @JsonIgnoreYalnızca getter yöntemine ekle

Yanıtlar:


481

Bunun nasıl yapılacağı, kullandığınız Jackson sürümüne bağlıdır. Bu , 1.9 sürümü etrafında değişti , bundan önce @JsonIgnore, alıcıya ekleyerek bunu yapabilirsiniz .

Hangisini denedin:

Yalnızca getter yöntemine @JsonIgnore ekleyin

Bunu yapın ve@JsonProperty nesnenizdeki parola için ayarlayıcı yöntemine JSON "parola" alan adınız için belirli bir ek açıklama ekleyin .

Jackson son sürümleri daha eklemiş READ_ONLYve WRITE_ONLYaçıklama argümanlar için JsonProperty. Böylece şöyle bir şey de yapabilirsiniz:

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

Dokümanları burada bulabilirsiniz .


2
Jackson JSON için gist.github.com/thurloat/2510887 yalnızca serileştirmeyi göz ardı et
Hadas

1
AFAIK, ayarlayıcıyı uygulamanız ve açıklama eklemeniz gerekir. Ben sadece serileştirme için alıcı istiyorum. Bahsettiğiniz geçici nedir? Bu bir JPA notu AFAIK
Matt Broekhuis

3
Ayrıca, @JsonProperty'yi alanın kendisinden kaldırdığınızdan emin olun, aksi takdirde alıcı / ayarlayıcı ek açıklamalarınızı geçersiz kılacaktır
Anton Soradoi

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

1
Jackson ek açıklamaları 2.5 daha sonraki bir özelliğe sahip değildir. Jackson-ek açıklamaları 2.6.3 yapar
radiantRazor

98

Bunu başarmak için tek ihtiyacımız olan iki ek açıklama:

  1. @JsonIgnore
  2. @JsonProperty

Kullanın @JsonIgnoresınıf üyesi ve gaz giderici üzerinde ve @JsonPropertyonun setter üzerinde. Örnek bir örnek bunu yapmanıza yardımcı olacaktır:

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
jackson 2.6.4 ile benim için çalışan tek şey bu. @JsonProperty (access = Access.WRITE_ONLY) kullanmak için elimden geleni yaptım ama benim için çalışmadı.
cirovladimir

77

Sürüm 2.6'dan beri: daha sezgisel bir yol, com.fasterxml.jackson.annotation.JsonPropertyek açıklamaları sahada kullanmaktır:

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

Bir alıcı varsa bile, alan değeri serileştirme dışında bırakılır.

JavaDoc diyor ki:

/**
 * 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

Bunun tersine ihtiyacınız varsa, sadece kullanın Access.READ_ONLY.


1
Neden bu kadar az oy kullanıldığını anlamıyorum, bu sorunu çözmek için zarif bir yol, bir cazibe gibi çalışıyor. Alıcı, ayarlayıcı ve alana açıklama eklemeye gerek yoktur. Sadece alan. Teşekkürler.
CROSP

Bu, 2.6 sürümünden beri kullanılabilir, bkz. Fastxml.github.io/jackson-annotations/javadoc/2.6/com/…
Daniel Beer

2.6+ kullanıcı için muhtemelen en iyi yanıt.
David Dossot

Org.codehaus.jackson.annotate içe aktarma işlemini kullanmadığınızdan emin olun . @ DanielBeer'in çözümü Jackson 2.6.3 için çalışıyor. Bu Jackson'ın güncellendiği kabul edilen cevap olmalı.
Kent Bull

13

Benim durumumda, ben bir Spring MVC denetleyicisinden döndüğüm nesneleri otomatik olarak (de) serileştirme var (Spring 4.1.6 ile @RestController kullanıyorum). Aksi takdirde, hiçbir şey yapmadı com.fasterxml.jackson.annotation.JsonIgnoreyerine kullanmak zorunda kaldım org.codehaus.jackson.annotate.JsonIgnore.


1
Bu, @JsonIgnore'un Jackson tarafından neden onurlandırılmadığının kaynağını bulmama gerçekten yardımcı olan son derece kullanışlı bir cevap ... teşekkürler!
Clint Eastwood

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
Kodun nasıl çalıştığına dair kısa bir açıklama bile vermek gelecekte yardımcı olabilir.
KWILLIAMS

Peki !! Burada ne deniyorsun? Daha fazla oy mu alıyorsunuz? lol
Balaji Boggaram Ramanarayan

0

Bunu ele almanın bir başka kolay yolu da argümanı kullanmaktır. allowSetters=true ek açıklamada kullanmaktır. Bu, parolanın dto'nuzdan serileştirilmesine izin verir, ancak nesne içeren bir yanıt gövdesine serileştirmez.

misal:

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

Her ikisi de foove barnesnede doldurulur, ancak bir yanıt gövdesine sadece foo yazılır.


Bu benim hatamdı, pasajı zaten düzelttiğinizi fark etmedim. Değişikliklerinize baktığımda, Groovy'de yazdığım yıllar beni aldı ve Java'ya çevirim biraz kaba oldu. Afedersiniz!
Dhandley
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.