जैकसन को केवल खेतों का उपयोग करने के लिए कैसे निर्दिष्ट करें - अधिमानतः विश्व स्तर पर


189

डिफ़ॉल्ट जैकोन व्यवहार दोनों गुणों (गेटर्स और सेटर) का उपयोग करता है और सीरियसली और जॉन्सन के लिए डिसेरिएलाइज़ करने के लिए फ़ील्ड का उपयोग करता है।

मैं क्रमिक विन्यास के विहित स्रोत के रूप में खेतों का उपयोग करना चाहूंगा और इस तरह से जैकसन को गुणों को देखना नहीं चाहता।

मैं एनोटेशन के साथ एक व्यक्तिगत वर्ग के आधार पर कर सकता हूं:

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

लेकिन मैं इसे हर एक वर्ग पर नहीं डालना चाहता ...

क्या विश्व स्तर पर इसे कॉन्फ़िगर करना संभव है? ऑब्जेक्ट मैपर में कुछ जोड़ें?


1
टिम ने अच्छा जवाब दिया। एक और संभावना यह है कि यदि आपके पास एक सामान्य आधार वर्ग है, तो आप उस पर वर्ग एनोटेशन डाल सकते हैं; एनोटेशन जैक्सन द्वारा विरासत में मिले हैं।
स्टेक्समैन

1
मुझे लगता है कि मैंने ऐसा करने की कोशिश की, लेकिन ऐसा लगता है कि आपको सब क्लास को यह बताना होगा कि बेस केस क्या परिभाषित करता है ...
माइकल विल्स

2
नहीं, जब तक उप-वर्ग वर्ग एनोटेशन को ओवरराइड नहीं करता है, तब तक माता-पिता की एनोटेशन दिखाई देती हैं जैसे कि वे सब-क्लास डेफिनेशन का हिस्सा थे (यदि नहीं, तो यह एक बग होगा)। यह जरूरी नहीं है कि जेडीके एनोटेशन से कैसे निपटता है, लेकिन जैक्सन एनोटेशन (यहां तक ​​कि एनोटेशन के लिए) के लिए पूर्ण उत्तराधिकार को लागू करता है।
स्टेक्समैन

INFER_PROPERTY_MUTATORSझंडे से सावधान रहें । यदि दृश्यमान गटर या क्षेत्र है तो यह बसने वालों की दृश्यता को प्रभावित करता है।
ओन्द्रा kaसुका

जवाबों:


157

आप इस तरह अलग-अलग ObjectMappers कॉन्फ़िगर कर सकते हैं:

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

यदि आप चाहते हैं कि यह विश्व स्तर पर स्थापित हो, तो मैं आमतौर पर एक रैपर वर्ग के माध्यम से कॉन्फ़िगर किए गए मैपर का उपयोग करता हूं।


3
अच्छा, हालाँकि मुझे लगता है कि आपको चेकर (withXxx () विधियाँ आमतौर पर एक नई वस्तु बनाने की भी आवश्यकता हो सकती है)। तो कुछ ऐसा है जैसे 'mapper.setVisibilityChecker (mapper.getVisibilityChecker (), with ...);'
स्टेक्समैन

@StaxMan setVisibilityChecker पर अच्छी कॉल, मैंने प्रतिबिंबित करने के लिए उत्तर संपादित किया।
केविन बोवर्क्स

42
withGetterVisibilityis*तरीकों को कवर नहीं करता है , लेकिन withIsGetterVisibilityउनके लिए है।
क़ुर्ब

13
setVisibilityCheckerपदावनत किया गया है। setVisibilityइसके बजाय उपयोग करें ।
0x7d7b

1
यही वह चीज है जिसकी मुझे जरूरत थी! इस कॉन्फ़िगरेशन ने मुझे आसानी से हाइबरनेट संस्थाओं को डीटीओ में बदलने के लिए मिक्सिन का उपयोग करने की अनुमति दी। डिफ़ॉल्ट रूप से ObjectMapper सब कुछ क्रमबद्ध करता है और एक मिक्सिन को निर्दिष्ट करना होगा कि कौन से गुणों को अनदेखा किया जाए (यानी एक प्रतिच्छेदन के बजाय एक घटाव)।
18

150

जैक्सन 2.0 में और बाद में आप बस उपयोग कर सकते हैं:

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

ऑटोडेटेक्शन को बंद करने के लिए।


1
हाय दोस्तों, मैं जैक्सन 1.9.0 जार का उपयोग कर रहा हूं। मुझे अतिरिक्त जोंस प्रॉपर्टी मिल रही है, जबकि ऑब्जेक्ट को जौन स्ट्रिंग में क्रमबद्ध किया जा रहा है। मुझे json स्ट्रिंग प्राप्त करने की आवश्यकता है, जिसमें केवल @JsonProperty के साथ उल्लिखित चर हैं। क्या आप कृपया इस पर मेरी मदद कर सकते हैं?
शब्दजाल

7
आप ओपी प्रश्न में उल्लिखित कक्षा एनोटेशन के साथ शुरू कर सकते हैं: @JsonAutoDetect(fieldVisibility = Visibility.NONE, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)अगला, आपको प्रत्येक संपत्ति को एनोटेट करना होगा जिसे आप शामिल करना चाहते हैं@JsonProperty
lukk

धन्यवाद! इससे पहले, मुझे कई कोड उदाहरण मिल गए हैं जहां संपत्ति के उत्तराधिकारी के बजाय JsonMethod को संदर्भित किया गया था। यदि आप JsonMethod को खोजते हैं, तो आपको शायद ही कभी प्रॉपर्टीकाउंटर के लिंक मिलते हैं ... उत्तराधिकारी कलाकृतियों में प्रतिस्थापन वर्ग के नाम खोजने का सबसे अच्छा तरीका क्या है? कठिन और बुरा हो सकता है, नहीं?
1919 को दार्शनिक

38

विशेष रूप से boolean is*()पाने वालों के लिए:

मैंने बहुत समय बिताया है, न ही नीचे क्यों

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

न यह

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

मेरे बुलियन गेट्टर / सेटर के लिए काम किया।

समाधान सरल है:

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

अद्यतन: वसंत-बूट इसे कॉन्फ़िगर करने की अनुमति देता है:

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

सामान्य अनुप्रयोग गुण देखें # JACKSON


1
क्या आप यह विस्तृत कर सकते हैं कि बीन क्लास के लिए कितना सरल समाधान लागू किया जाना चाहिए?
पावेल निदोबा

1
धन्यवाद। वह गीजर मेरे लिए दिन बचा रहा।
grinch

यह सवाल का जवाब नहीं है और भ्रामक है।
ओन्द्रा kaižka

14

जैक्सन के लिए 1.9.10 मैं उपयोग करता हूं

ObjectMapper mapper = new ObjectMapper();

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

ऑटो समर्पण की बारी।


2
यह ही तरीका है। धन्यवाद।
cuneytykaya

आश्चर्य है कि क्या ऐसा करने और "ऑटो का पता लगाने" को अक्षम करने के बीच कोई अंतर है।
xenoterracide

10

इसके बारे में कैसे: मैंने इसे एक मिक्सिन के साथ इस्तेमाल किया

गैर-आज्ञाकारी वस्तु

@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 {}

उपयोग:

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

ऐसा कुछ भी नहीं है जो कहता है कि आप किसी भी वर्ग की संख्या को कम नहीं कर सकते हैं और एक ही मिश्रण को लागू कर सकते हैं।

यदि आप मिश्रणों से परिचित नहीं हैं, तो वे वैचारिक रूप से सरल हैं: मिश्रण की संरचना सुपर क्लास (जैकसन के अनुसार, जहां तक ​​जेवीएम का संबंध है) के अनुसार सुपर क्लास पर लगाया गया है।


3

यदि आप अपने कॉन्फ़िगरेशन के बारे में चिंता किए बिना विश्व स्तर पर ऐसा करने का एक तरीका चाहते हैं ObjectMapper, तो आप अपना खुद का एनोटेशन बना सकते हैं:

@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 {
}

अब आपको बस अपनी कक्षाओं को एनोटेट करना है @JsonExplicitऔर आप जाने के लिए अच्छे हैं!

यह भी सुनिश्चित @JsonAutoDetectकरने के लिए कि आप अपने प्रोग्राम के साथ क्या काम करते हैं, यह निर्धारित करने के लिए उपरोक्त कॉल को संपादित करना सुनिश्चित करें ।

मेरे बारे में जानने के लिए https://stackoverflow.com/a/13408807 पर क्रेडिट करें@JacksonAnnotationsInside


3

यदि आप स्प्रिंग बूट का उपयोग करते हैं, तो आप जैक्सन को विश्व स्तर पर कॉन्फ़िगर कर सकते हैं:

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

}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.