Jackson: Alan serileştirmesini önleme


163

Parola alanı olan bir varlık sınıfı var:

class User {
    private String password;

    //setter, getter..
}

Serileştirme sırasında bu alanın atlanmasını istiyorum. Ama yine de serileştirebilmeli. Bu, istemcinin bana yeni bir şifre gönderebilmesi için gereklidir, ancak mevcut şifreyi okuyamaz.

Bunu Jackson ile nasıl başarabilirim?


1
Serileştirmek istemiyorsunuz, ancak serisini kaldırabilmek mi istiyorsunuz? Bu imkansız, diyebilirim. Bir kutuya bir çerez koymazsanız, bu kutudan alamazsınız.
Alexis Dufrenoy

1
@Traroth: Ama YENİ bir çerez koyabilirim. Sadece uygun bir ek açıklama arıyorum, ancak bu kesinlikle elle yapılabilir.
sonu

8
Hızlı yorum: teknik olarak, kullanılan bir ayarlayıcıya sahip olmak (özel olanlar bile otomatik olarak algılanır) ve yalnızca erişimciyi (genel alan veya alıcı olmadan) atlamak tamamen mümkündür. @JsonIgnoreAlıcıya, ancak @JsonPropertyayarlayıcıya da eklemek mümkündür , bu durumda işler seri hale getirilmez, ancak serileştirilebilir.
StaxMan

4
Bu soruya bir cevap almayı düşünür müsünüz? (Diğerlerinden birkaçı birkaç yaşında ve hala kabul edilmiyor ... Lütfen incelemeyi düşünün!) :) Tam açıklama - Bu soruların hiçbirine cevap vermiyorum.
Barett

Yanıtlar:


187

Olarak işaretleyebilirsiniz @JsonIgnore.

1.9 ile, alıcıyı seri dışı bırakmak ancak serileştirmek için ayarlayıcı @JsonIgnoreiçin ekleyebilirsiniz @JsonProperty.


6
@JsonIgnore, serileştirmeyi de önler. Geçici için - Ben kontrol edeceğim.
sonu

98
1.9 ile, alıcıyı seri dışı bırakmak ancak serileştirmek için ayarlayıcı @JsonIgnoreiçin ekleyebilirsiniz @JsonProperty.
StaxMan

StaxMan'ın cevabı cevap olmalı, değil mi? Neden hala bir yorum ... ... ..?
Saravanabalagi Ramachandran

geçici benim için çalışmıyor gibi görünüyor, ben alan "geçici" i serilized / serileştirilmiş olmasını istemiyorum işaretlenmiş.
rohith

Bu cevap daha önce kullanan önerdi transient(olduğu gibi private transient String password;), ancak kamu getters ile geçici alanlar göz ardı edilir sürece MapperFeature.PROPAGATE_TRANSIENT_MARKER etkindir.
tom

96

StaxMan'ın söylediklerini gösteren bu benim için işe yarıyor

private String password;

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

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

12
Hangi Json bağımlılığını kullanıyorsunuz? Bu com.fasterxml.jackson ile çalışmaz
Alexander Burakevych

3
Teşekkürler! @JsonIgnoresahada gerekli değil gibi görünüyor.
Ferran Maylinch

jack.fadxml.jackson.annotation.JsonIgnore jackson-annotations- <version> .jar
mvmn

Bunu denedim ve benim için çalışmıyor. V2.8 kullanıyorum. Herhangi bir yardım?
Maz

36

Kolay yol, alıcılarınızı ve ayarlayıcılarınızı açıklamaktır.

Düz metin parolasını hariç tutmak için değiştirilen orijinal örnek aşağıdadır, ancak daha sonra parola alanını şifrelenmiş metin olarak döndüren yeni bir yönteme not ekleyin.

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

Jackson 2.6'dan başlayarak , bir özellik salt okunur veya salt yazılır olarak işaretlenebilir. Her iki erişimcideki ek açıklamaları hacklemekten daha basittir ve tüm bilgileri tek bir yerde tutar:

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

Bu harika bir çözüm, basit, çalışıyor. Teşekkürler.
dhqvinh

17

Bunun dışında @JsonIgnorebirkaç başka olasılık daha var:

  • Alanları koşullu olarak filtrelemek için JSON Görünümlerini kullanın (varsayılan olarak, serileştirme için kullanılmaz; 2.0'da kullanılabilir ancak serileştirme, serileştirme konusunda farklı görünümler kullanabilirsiniz)
  • @JsonIgnoreProperties sınıfta yararlı olabilir

10

transientbenim için bir çözüm. Teşekkürler! Java'ya özgüdür ve başka bir çerçeveye özgü ek açıklama eklemenizi önler.


2
Özniteliğiniz ORM dahil değil, gerçekten geçici ise işe yarar .... Jackson için kilitli olsa da, benim durumumda daha ilginç bulundu @JsonIgnore bulundu, ama bu iyi bir ödünleşim
Joao Pereira

3
Kendi ek açıklamanızı oluşturup JsonIgnore ve JacksonAnnotationsInside tarafından ek açıklama eklerseniz, jackson'a kilitlenmeniz gerekmez. Bu şekilde, serileştiricileri değiştirirseniz, yalnızca kendi ek açıklamanızı değiştirmeniz gerekir.
DavidA

4

Parola için neden herkese açık bir alıcı yöntemi istediğinizi sormalısınız. Hazırda bekletme modu veya başka bir ORM çerçevesi özel alıcı yöntemiyle yapılır. Parolanın doğru olup olmadığını kontrol etmek için şunu kullanabilirsiniz:

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

Aslında bunun çözümü düşünmenin en iyi yolu olduğunu düşünüyorum. İhtiyacınız olan şeyleri özel yapmak ve bunları nesnenin kendisinden kontrol etmek daha mantıklıdır.
arcynum

2

Jackson, serileştirme ve serileştirme sırasında alanların filtrelenmesine yardımcı olan SimpleBeanPropertyFilter adlı bir sınıfa sahiptir; küresel olarak değil. Bence istediğin buydu.

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

    //setter, getter..
}

Sonra kodunuzda:

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);

Bu, passwordalanın serileştirilmesini önleyecektir . Ayrıca passwordalanların olduğu gibi serisini kaldırabilirsiniz . Yalnızca hiçbir nesnenin ObjectMapper nesnesine uygulanmadığından emin olun.

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

0

değişkeni olarak ayarla

@JsonIgnore

Bu, değişkenin json serileştiricisi tarafından atlanmasına izin verir

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.