जब एक कंस्ट्रक्टर को @JsonCreator के साथ एनोटेट किया जाता है, तो उसके तर्क को @JsonProperty के साथ एनोटेट किया जाना चाहिए?


108

जैक्सन में, जब आप एक कंस्ट्रक्टर के साथ एनोटेट करते हैं, तो आपको @JsonCreatorइसके तर्कों को एनोटेट करना चाहिए @JsonProperty। तो यह कंस्ट्रक्टर

public Point(double x, double y) {
    this.x = x;
    this.y = y;
}

यह बन जाता है:

@JsonCreator
public Point(@JsonProperty("x") double x, @JsonProperty("y") double y) {
    this.x = x;
    this.y = y;
}

मुझे समझ नहीं आता कि यह क्यों जरूरी है। क्या आप समझा सकते हैं?

जवाबों:


112

जैक्सन को यह जानना होगा कि निर्माणकर्ता को JSON ऑब्जेक्ट से फ़ील्ड्स को किस क्रम में पारित करना है। प्रतिबिंब का उपयोग करके जावा में पैरामीटर नाम तक पहुंचना संभव नहीं है - इसलिए आपको एनोटेशन में इस जानकारी को दोहराना होगा।


9
यह
जावा

12
@MariuszS यह सच है लेकिन यह पोस्ट बताती है कि Java8 संकलक ध्वज और एक जैक्सन मॉड्यूल की मदद से बाहरी एनोटेशन से कैसे छुटकारा पाया जा सकता है। मैंने दृष्टिकोण का परीक्षण किया है और यह काम करता है।
क्वांटम

Ofcourse, एक आकर्षण की तरह काम करता है :) docs.oracle.com/javase/tutorial/reflect/member/…
MariuszS

52

पैरामीटर नाम सामान्य रूप से रनटाइम पर जावा कोड द्वारा सुलभ नहीं होते हैं (क्योंकि यह संकलक द्वारा ड्रॉप होता है), इसलिए यदि आप चाहते हैं कि कार्यक्षमता आपको या तो जावा 8 की अंतर्निहित कार्यक्षमता का उपयोग करने की आवश्यकता है या पहुंच प्राप्त करने के लिए पैरानेमर जैसी लाइब्रेरी का उपयोग करें। यह करने के लिए।

तो जैक्सन का उपयोग करते समय कंस्ट्रक्टर के तर्कों के लिए एनोटेशन का उपयोग नहीं करने के लिए, आप इन जैक्सन हेडर में से किसी एक का उपयोग कर सकते हैं:

जैक्सन मॉड्यूल पैरामीटर-नाम

यह मॉड्यूल आपको जावा 8 का उपयोग करते समय एनोटेशन-फ्री कंस्ट्रक्टर तर्क प्राप्त करने की अनुमति देता है । इसका उपयोग करने के लिए आपको पहले मॉड्यूल को पंजीकृत करने की आवश्यकता है:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ParameterNamesModule());

फिर -परामेटर्स ध्वज का उपयोग करके अपना कोड संकलित करें:

javac -parameters ...

लिंक: https://github.com/FasterXML/jackson-modules-java8/tree/master/parameter-names

जैक्सन मॉड्यूल-paranamer

यह अन्य एक बस आपको मॉड्यूल को पंजीकृत करने या एक एनोटेशन आत्मनिरीक्षण (लेकिन दोनों टिप्पणियों के रूप में इंगित नहीं किया गया है) को कॉन्फ़िगर करने की आवश्यकता है। यह आपको 1.8 से पहले जावा के संस्करणों पर एनोटेशन-फ्री कंस्ट्रक्टर के तर्क का उपयोग करने की अनुमति देता है ।

ObjectMapper mapper = new ObjectMapper();
// either via module
mapper.registerModule(new ParanamerModule());
// or by directly assigning annotation introspector (but not both!)
mapper.setAnnotationIntrospector(new ParanamerOnJacksonAnnotationIntrospector());

लिंक: https://github.com/FasterXML/jackson-modules-base/tree/master/paraner


28

Jdk8 के साथ निर्माण एनोटेशन से बचना संभव है जहां वैकल्पिक रूप से कंपाइलर निर्माण मापदंडों के नाम के साथ मेटाडेटा पेश करेगा। फिर जैक्सन-मॉड्यूल-पैरामीटर-नाम मॉड्यूल जैक्सन के साथ इस कंस्ट्रक्टर का उपयोग कर सकते हैं। आप जैक्सन पर एनोटेशन के बिना एक उदाहरण देख सकते हैं



6

क्योंकि Java bytecode मेथड या कंस्ट्रक्टर के तर्कों के नाम को बरकरार नहीं रखता है।


अब और सच नहीं है: docs.oracle.com/javase/tutorial/reflect/member/…
MariuszS

1
@MariuszS वास्तव में, लेकिन चूंकि यह एक नया (और गैर-डिफ़ॉल्ट कंपाइलर ध्वज) है, जैक्सन को इसके @JsonPropertyएनोटेशन का समर्थन करना जारी रखना होगा
lcfd

6

कोई बस java.bean.ConstructorProperties एनोटेशन का उपयोग कर सकता है - यह बहुत कम क्रिया है और जैक्सन भी इसे स्वीकार करता है। उदाहरण के लिए :

  import java.beans.ConstructorProperties;

  @ConstructorProperties({"answer","closed","language","interface","operation"})
  public DialogueOutput(String answer, boolean closed, String language, String anInterface, String operation) {
    this.answer = answer;
    this.closed = closed;
    this.language = language;
    this.anInterface = anInterface;
    this.operation = operation;
  }

4

जब मैं इसे सही ढंग से समझता हूं , तो आप डिफॉल्ट कंस्ट्रक्टर को एक पैरामीटर के साथ बदल देते हैं और इसलिए JSON कुंजियों का वर्णन करना होता है, जिनका उपयोग कंस्ट्रक्टर को कॉल करने के लिए किया जाता है।


3

जैसा कि एनोटेशन दस्तावेज़ीकरण में बताया गया है , एनोटेशन इंगित करता है कि तर्क नाम का उपयोग संपत्ति के नाम के रूप में बिना किसी संशोधन के किया जाता है, लेकिन इसे अलग-अलग नाम निर्दिष्ट करने के लिए गैर-रिक्त मान में निर्दिष्ट किया जा सकता है:


0

बस इसके पार आओ और कहीं जवाब मिला। आप 2.7.0 से नीचे एनोटेशन का उपयोग कर सकते हैं

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class Point {
    final private double x;
    final private double y;

    @ConstructorProperties({"x", "y"})
    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.