Jackson'ı yalnızca alanları kullanmak için nasıl belirtilir - tercihen küresel


191

Varsayılan jackon davranışı, json'a serileştirmek ve serisini kaldırmak için hem özellikleri (alıcılar ve ayarlayıcılar) hem de alanları kullanıyor gibi görünüyor.

Alanları kanonik serileştirme yapılandırma kaynağı olarak kullanmak istiyorum ve böylece jackson özellikleri hiç bakmak istemiyorum.

Ek açıklama ile bunu bireysel sınıf bazında yapabilirim:

 @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)

Ama bunu her sınıfa koymak istemiyorum ...

Bunu global olarak yapılandırmak mümkün mü? Nesne Eşleyici'ye biraz eklemek ister misiniz?


1
Tim iyi bir cevap verdi. Başka bir olasılık, ortak bir temel sınıfınız varsa, buna sınıf ek açıklamaları ekleyebilirsiniz; ek açıklamalar Jackson tarafından miras alınır.
StaxMan

1
Sanırım bunu denedim, ama alt sınıflara temel davanın tanımladığı şeyi kullanmanız gerektiğini söylemelisiniz ...
Michael Wiles

2
Hayır, alt sınıf sınıf ek açıklamasını geçersiz kılmadığı sürece, üst öğenin ek açıklamaları alt sınıf tanımının bir parçasıymış gibi görünür (değilse, bu bir hata olur). JDK ek açıklamalarla bu şekilde ilgilenmez, ancak Jackson ek açıklamalara (yöntem ek açıklamaları için bile) tam miras uygular.
StaxMan

INFER_PROPERTY_MUTATORSBayrağa dikkat edin . Görünür bir alıcı veya alan varsa ayarlayıcıların görünürlüğünü zorlar.
Ondra Žižka

Yanıtlar:


157

Tek tek ObjectMappers'ı şu şekilde yapılandırabilirsiniz:

ObjectMapper mapper  = new ObjectMapper();
mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));

Genel olarak ayarlanmasını istiyorsanız, genellikle bir sarmalayıcı sınıfı aracılığıyla yapılandırılmış bir eşleştiriciye erişirim.


3
İyi, ben de denetleyicisi ayarlamak gerekebilir düşünüyorum (withXxx () yöntemleri genellikle yeni bir nesne oluşturmak). Yani 'mapper.setVisibilityChecker (mapper.getVisibilityChecker (). İle ...);'
StaxMan

@StaxMetVisibilityChecker üzerinde iyi bir çağrı, yansıtmak için cevabı düzenledim.
Kevin Bowersox

42
withGetterVisibilityis*yöntemleri kapsamıyor , ama withIsGetterVisibilityonlar için var .
qerub

13
setVisibilityCheckerkullanımdan kaldırıldı. setVisibilityBunun yerine kullanın .
0x7d7b

1
Tam da ihtiyacım olan şey bu! Bu yapılandırma, Hazırda Bekletme varlıklarını kolayca DTO'lara dönüştürmek için bir Mixin kullanmamı sağladı. Varsayılan olarak, ObjectMapper her şeyi serileştirir ve bir Mixin hangi özelliklerin yoksayılacağını belirtmek zorunda kalır (yani bir kavşak yerine bir çıkarma).
Lezzetli

150

Jackson 2.0 ve sonraki sürümlerde şunları kullanabilirsiniz:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;   

...

ObjectMapper mapper = new ObjectMapper();    
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

otomatik algılamayı kapatmak için.


1
Merhaba arkadaşlar, Jackson 1.9.0 kavanoz kullanıyorum. Nesneyi json dizisine serileştirirken ek json özelliği alıyorum. @JsonProperty ile sadece belirtilen değişkenleri içeren json dize almanız gerekiyor. Bana bu konuda yardımcı olabilir misiniz?
jrhamza

7
OP sorusunda belirtilen sınıf notu ile başlayabilirsiniz: @JsonAutoDetect(fieldVisibility = Visibility.NONE, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)Daha sonra, dahil etmek istediğiniz her mülke not @JsonProperty
eklemelisiniz

Teşekkürler! Daha önce, PropertyAccessor yerine JsonMethod'a başvurulan birçok kod örneği buldum. JsonMethod için arama yaparsanız, nadiren PropertyAccessor'a bağlantılar alırsınız ... Ardıl eserlerde yedek sınıf isimlerini bulmanın en iyi yolu nedir? Sert ve kötü olabilir, değil mi?
philburns

38

Özellikle boolean is*()alıcılar için:

Aşağıdakilerin hiçbiri için neden çok zaman harcadım

  @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)

ne bu

  setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);
  setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
  setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

Boole Getter / Setter'im için çalıştı.

Çözüm basit:

  @JsonAutoDetect(isGetterVisibility = Visibility.NONE, ...          
  setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE);

GÜNCELLEME: yay önyüklemesine izin verilir yapılandırın:

jackson:
  visibility.field: any
  visibility.getter: none
  visibility.setter: none
  visibility.is-getter: none

Bkz. Ortak uygulama özellikleri # JACKSON


1
Fasulye sınıfına ne kadar basit bir çözüm uygulanması gerektiğini açıklayabilir misiniz?
Pavel Niedoba

1
Teşekkür ederim. Bu, günü benim için kurtardı.
grinch

Bu sorunun cevabı değildir ve oldukça yanıltıcıdır.
Ondra Žižka

14

jackson 1.9.10 için kullanıyorum

ObjectMapper mapper = new ObjectMapper();

mapper.setVisibility(JsonMethod.ALL, Visibility.NONE);
mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);

otomatik dedeksiyonu açmak için.


2
Bu şekilde. Teşekkürler.
cuneytykaya

bunu yapmak ve "otomatik algılamaları" devre dışı bırakmak arasında herhangi bir fark olup olmadığını merak ediyorum.
Ocak'ta xenoterracide

10

Buna ne dersin: Bir mixin ile kullandım

uyumlu olmayan nesne

@Entity
@Getter
@NoArgsConstructor
public class Telemetry {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long pk;
    private String id;
    private String organizationId;
    private String baseType;
    private String name;
    private Double lat;
    private Double lon;
    private Instant updateTimestamp;
}

mixin:

@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
public static class TelemetryMixin {}

Kullanımı:

    ObjectMapper om = objectMapper.addMixIn(Telemetry.class, TelemetryMixin.class);
    Telemetry[] telemetries = om.readValue(someJson, Telemetry[].class);

Herhangi bir sayıda sınıfı öngörebileceğinizi ve aynı karışımı uygulayamayacağınızı söyleyen hiçbir şey yoktur.

Karışımlara aşina değilseniz, kavramsal olarak basittirler: Karışımın yapısı hedef sınıfa süper empoze edilir (jackson'a göre, JVM ile ilgili olarak değil).


3

Bunu, yapılandırmanızdan endişelenmeden global olarak yapmanın bir yolunu ObjectMapperistiyorsanız, kendi ek açıklamanızı oluşturabilirsiniz:

@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonAutoDetect(
        getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE,
        setterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.NONE,
        creatorVisibility = JsonAutoDetect.Visibility.NONE
)
public @interface JsonExplicit {
}

Şimdi sadece derslerinize not eklemeniz gerekiyor @JsonExplicitve hazırsınız!

Ayrıca @JsonAutoDetect, programınızla işe yarayan değerlere sahip olduğunuzdan emin olmak için yukarıdaki çağrıyı düzenlediğinizden emin olun.

Hakkında bilgi edinmeme yardımcı olduğu için https://stackoverflow.com/a/13408807 adresine teşekkür ederiz.@JacksonAnnotationsInside


3

Spring Boot kullanıyorsanız, Jackson'ı global olarak aşağıdaki gibi yapılandırabilirsiniz :

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class JacksonObjectMapperConfiguration implements Jackson2ObjectMapperBuilderCustomizer {

    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        jacksonObjectMapperBuilder.visibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
        jacksonObjectMapperBuilder.visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
        jacksonObjectMapperBuilder.visibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY);
    }

}
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.