EDIT : जैक्सन के अनुरक्षकों द्वारा एक ब्लॉग पोस्ट में, यह लगता है कि 2.12 में कंस्ट्रक्टर इंजेक्शन के संबंध में सुधार देखने को मिल सकते हैं। (इस एडिट के समय वर्तमान संस्करण 2.11.1 है)
कंस्ट्रक्टर रचनाकारों के ऑटो-डिटेक्शन में सुधार करें, जिसमें अस्पष्ट 1-तर्क निर्माणकर्ताओं (गुणों बनाम प्रतिनिधि) के साथ समस्याओं को हल करना / हल करना शामिल है
यह अभी भी जैक्सन डेटाबैन्ड 2.7.0 के लिए सही है।
जैक्सन @JsonCreator
एनोटेशन 2.5 जैवाडोक या जैक्सन एनोटेशन प्रलेखन व्याकरण ( निर्माता एस और फैक्टरी विधि) रों ) दें वास्तव में विश्वास है कि एक कर सकते हैं निशान कई निर्माताओं।
मार्कर एनोटेशन जिसका उपयोग निर्माणकर्ता और कारखाने के तरीकों को परिभाषित करने के लिए किया जा सकता है ताकि संबंधित वर्ग के नए उदाहरणों का तुरंत उपयोग किया जा सके।
उस कोड को देखते हुए जहां रचनाकारों की पहचान की जाती है, ऐसा लगता है कि जैक्सन ओवरलोड निर्माणकर्ताओं कीCreatorCollector
अनदेखी कर रहा है क्योंकि यह केवल निर्माता के पहले तर्क की जांच करता है ।
Class<?> oldType = oldOne.getRawParameterType(0);
Class<?> newType = newOne.getRawParameterType(0);
if (oldType == newType) {
throw new IllegalArgumentException("Conflicting "+TYPE_DESCS[typeIndex]
+" creators: already had explicitly marked "+oldOne+", encountered "+newOne);
}
oldOne
पहला रचनाकार रचनाकार है।
newOne
अतिभारित रचनाकार है।
इसका मतलब है कि कोड की तरह यह काम नहीं करेगा
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
this.country = "";
}
@JsonCreator
public Phone(@JsonProperty("country") String country, @JsonProperty("value") String value) {
this.value = value;
this.country = country;
}
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
लेकिन यह कोड काम करेगा:
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
enabled = true;
}
@JsonCreator
public Phone(@JsonProperty("enabled") Boolean enabled, @JsonProperty("value") String value) {
this.value = value;
this.enabled = enabled;
}
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\",\"enabled\":true}", Phone.class).value).isEqualTo("+336");
यह थोड़ा हैकरी है और भविष्य का प्रमाण नहीं हो सकता है ।
प्रलेखन अस्पष्ट है कि ऑब्जेक्ट निर्माण कैसे काम करता है; हालांकि मैं कोड से क्या इकट्ठा करता हूं, यह है कि विभिन्न तरीकों को मिलाना संभव है:
उदाहरण के लिए किसी के पास एक स्थिर कारखाना विधि हो सकती है, जिसके साथ एनोटेट किया गया है @JsonCreator
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
enabled = true;
}
@JsonCreator
public Phone(@JsonProperty("enabled") Boolean enabled, @JsonProperty("value") String value) {
this.value = value;
this.enabled = enabled;
}
@JsonCreator
public static Phone toPhone(String value) {
return new Phone(value);
}
assertThat(new ObjectMapper().readValue("\"+336\"", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\",\"enabled\":true}", Phone.class).value).isEqualTo("+336");
यह काम करता है लेकिन यह आदर्श नहीं है। अंत में, यह समझ में आ सकता है, उदाहरण के लिए, यदि JSON वह गतिशील है, तो शायद किसी एनोटेट निर्माणकर्ताओं के मुकाबले पेलोड विविधताओं को संभालने के लिए प्रतिनिधि प्रतिनिधि का उपयोग करना चाहिए।
यह भी ध्यान दें कि जैक्सन प्राथमिकता से रचनाकारों का आदेश देता है , उदाहरण के लिए इस कोड में:
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
}
@JsonCreator
public Phone(Map<String, Object> properties) {
value = (String) properties.get("value");
}
assertThat(new ObjectMapper().readValue("\"+336\"", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\",\"enabled\":true}", Phone.class).value).isEqualTo("+336");
इस बार जैक्सन कोई त्रुटि नहीं करेगा, लेकिन जैक्सन केवल प्रतिनिधि निर्माणकर्ता का उपयोग करेगा Phone(Map<String, Object> properties)
, जिसका अर्थ है कि इसका Phone(@JsonProperty("value") String value)
उपयोग कभी नहीं किया जाता है।