/ / जैक्सन मिक्स में जेनेरिक क्लास JAXBElement को बदलने के लिए <T> getValue () - java, xml, json, jaxb, jackson के पीछे टी

जैक्सन मिक्स ने जेनेरिक क्लास JAXBElement को बदलने के लिए <T> getValue () - java, xml, json, jaxb, jackson के पीछे अपने टी के साथ

मैं XML और JSON को एक ही JAXB एनोटेशन (का उपयोग करके) को बांधने की कोशिश कर रहा हूं JaxbAnnotationModule)।

XML <--> JAXB <--> Jackson <--> JSON

मुझे JAXB एनोटेशन का उपयोग करना होगा और उन्हें बदल नहीं सकता। मेरी समस्या यह है कि कुछ XML सामान्य वर्ग में परिवर्तित हो जाते हैं JAXBElement<T> एक वर्ग के बजाय T सीधे। यह JSON आउटपुट की ओर जाता है:

{
"JAXBElement":{
"name":"{http://www.opengis.net/wps/1.0.0}Capabilities",
"declaredType":"net.opengis.wps.v_1_0_0.WPSCapabilitiesType",
"scope":"javax.xml.bind.JAXBElement$GlobalScope",
"value":{
"ProcessOfferings":{  },
"Languages":{  },
"ServiceIdentification":{  },
"ServiceProvider":{  },
"OperationsMetadata":{  },
"version":"1.0.0",
"updateSequence":"1",
"service":"WPS",
"lang":"en-US"
},
"nil":false,
"globalScope":true,
"typeSubstituted":false
}
}

जबकि मैं इसके बजाय चाहता हूँ:

{
"Capabilities":{
"ProcessOfferings":{  },
"Languages":{  },
"ServiceIdentification":{  },
"ServiceProvider":{  },
"OperationsMetadata":{  },
"version":"1.0.0",
"updateSequence":"1",
"service":"WPS",
"lang":"en-US"
}
}

प्रकार की वास्तविक वस्तु T एक JAXBElement द्वारा लपेटा गया है। यह कुछ मूल तत्वों के लिए हो सकता है और ऑब्जेक्ट ट्री में भी कहीं भी घोंसला बना सकता है। अगर मैं बुलाऊं getValue() उस पर मुझे "वास्तविक वस्तु मिल जाएगी। लेकिन मैं ऐसा नहीं कर सकता" JAXBElement<T> जैक्सन और JSON के बीच जैक्सन एकमात्र दुभाषिया है क्योंकि मैं मूल तत्व नहीं हूं और मैं न तो JAXB- बाइंडिंग को बदल सकता हूं और न ही निर्मित वस्तुएं (कोड के कुछ अन्य हिस्से उनका उपयोग करते हैं, भी)।

तो मैंने पाया कि समस्या का समाधान क्या हो सकता है mixins:

// a mixin annotation that overrides the handling for the JAXBElement
public static interface JAXBElementMixin<T> {
@JsonValue
Object getValue();
}

ObjectMapper mapper = new ObjectMapper();
JaxbAnnotationModule module = new JaxbAnnotationModule();
mapper.registerModule(module);
mapper.addMixInAnnotations(JAXBElement.class, JAXBElementMixin.class);

यह अतिरिक्त तत्वों की समस्या को हल करता है लेकिन ऑब्जेक्ट के नाम का कारण बनता है JAXBElement के बजाय T (मेरे मामले में Capabilities):

{
"JAXBElement":{  // <------ Should be "Capabilities" because of type JAXBElement<Capabilities>
"ProcessOfferings":{  },
"Languages":{  },
"ServiceIdentification":{  },
"ServiceProvider":{  },
"OperationsMetadata":{  },
"version":"1.0.0",
"updateSequence":"1",
"service":"WPS",
"lang":"en-US"
}
}

प्रश्न:

किसी भी विचार मैं क्या कर सकता है (शायद एनोटेट JAXBElementMixin<T>) सही प्रकार प्राप्त करने के लिए Capabilities ऑब्जेक्ट नाम के रूप में (इसके बजाय अन्य वर्ग हैं Capabilities के रूप में रखा जा सकता है T, भी)?

कोई भी अन्य विचार किसी के क्रमांकन को कैसे छोड़ें JAXBElement<T> ऑब्जेक्ट ट्री में कहीं भी और इसके पीछे की वस्तु के क्रमांकन के साथ जारी है getValue() तरीका?

उत्तर:

जवाब के लिए 0 № 1

यह सीधे आपके प्रश्न का उत्तर नहीं है, लेकिन संभवतः आपके लक्ष्य को प्राप्त करने का एक नुस्खा है।

अगर आप सबसे ऊपर से छुटकारा पाना चाहते हैं JAXBElementक्यों, आप अपने लिए एक अतिरिक्त वर्ग उत्पन्न करने के लिए XJC को अनुकूलित नहीं करते Capabilities तत्व?

कुछ इस तरह:

<jaxb:bindings node="xs:element[@name="Capabilities"]">
<jaxb:class name="Capabilities"/>
</jaxb:bindings>

यह एक वर्ग उत्पन्न करना चाहिए Capabilities "@ XmlRootElement" के साथ एनोटेट किया गया। इस प्रकार आप "से छुटकारा पा लेंगे JAXBElement.


जवाब के लिए 0 № 2

जैक्सन समर्थन नहीं करता है JAXBElement, क्योंकि यह बहुत एक्सएमएल-विशिष्ट है और हैअन्य प्रारूपों के साथ काम करना मुश्किल है: जैक्सन JAXB समर्थन चीजों को काम करने के लिए एनोटेशन की जानकारी का उपयोग करने पर केंद्रित है, लेकिन लक्ष्य पूर्ण JAXB कार्यान्वयन नहीं है।

जैसे कि आपका सबसे अच्छा दांव यह है कि @lexicore क्या सुझाव देता है और इसके उपयोग से बचने की कोशिश करें JAXBElement.