का उपयोग कर एक और वर्ग पदानुक्रम में जेसन deserialization अब मैं जैक्सन के साथ काम कर रहा हूँ और मेरे पास इसके बारे में कुछ सवाल हैं।जैक्सन
सबसे पहले। मेरे पास दो सेवाएं हैं, पहले डेटा इकट्ठा करना और सेवा भेजना है और दूसरा यह डेटा प्राप्त करता है और, उदाहरण के लिए, इसे फ़ाइल में लॉग इन करें।
तो, पहले सेवा इस तरह वर्ग पदानुक्रम है:
+----ConcreteC
|
Base ----+----ConcreteA
|
+----ConcreteB
और दूसरा सेवा इस तरह वर्ग पदानुक्रम है:
ConcreteAAdapter extends ConcreteA implements Adapter {}
ConcreteBAdapter extends ConcreteB implements Adapter {}
ConcreteCAdapter extends ConcreteC implements Adapter {}
पहली सेवा ConcreteXAdapter
बारे में कुछ नहीं जानता है।
तरह से मैं पहली सर्विस पर डेटा भेज रहा:
Collection<Base> data = new LinkedBlockingQueue<Base>()
JacksonUtils utils = new JacksonUtils();
data.add(new ConcreteA());
data.add(new ConcreteB());
data.add(new ConcreteC());
...
send(utils.marshall(data));
...
public class JacksonUtils {
public byte[] marshall(Collection<Base> data) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream() {
@Override
public byte[] toByteArray() {
return buf;
}
};
getObjectMapper().writeValue(out, data);
return out.toByteArray();
}
protected ObjectMapper getObjectMapper() {
return new ObjectMapper();
}
public Object unmarshall(byte[] json) throws IOException {
return getObjectMapper().readValue(json, Object.class);
}
public <T> T unmarshall(InputStream source, TypeReference<T> typeReference) throws IOException {
return getObjectMapper().readValue(source, typeReference);
}
public <T> T unmarshall(byte[] json, TypeReference<T> typeReference) throws IOException {
return getObjectMapper().readValue(json, typeReference);
}
}
तो, मैं ConcreteXAdapter
का संग्रह में json desirialize को, ConcreteX
(ConcreteA -> ConcreteAAdapter, ConcreteB -> ConcreteBAdapter, ConcreteC -> ConcreteCAdapter
) का संग्रह में नहीं करना चाहता। यदि मैंने वर्णन किया है कि मैं प्राप्त करना चाहता हूं:
Collection [ConcreteAAdapter, ConcreteBAdapter, ConcreteCAdapter]
मैं यह कैसे कर सकता हूं?
objectMapper.registerSubtypes(
new NamedType(ConcreteAAdapter.class, "ConcreteA"),
new NamedType(ConcreteBAdapter.class, "ConcreteB"),
new NamedType(ConcreteCAdapter.class, "ConcreteC")
);
// note, that for lists you need to pass TypeReference explicitly
objectMapper.writerWithType(new TypeReference<List<Base>>() {})
.writeValueAsString(someList);
{
"@type" : "ConcreteA",
...
}
अक्रमांकन पर यह हो जाएगा::
उदाहरण BaseMixin वर्ग
दूसरी सेवा पर आप इस तरह BaseMixin निर्धारित कर सकते हैं तुरंत जवाब के लिए धन्यवाद! मैंने सवाल अपडेट किया। संक्षेप में, पहली सेवा 'ConcreteXAdapter' के बारे में कुछ भी नहीं जानता है। तो सवाल यह है कि जैक्सन को 'कंक्रीटएक्स एडाप्टर' बनाने के लिए कैसे कहना है यदि उसे जेसन में 'कंक्रीटएक्स' मिला। – pbespechnyi
इस मामले में मैं मैन्युअल रूप से पास करने का सुझाव दूंगा (जैसे "@type": "ConcreteA") और फिर संपत्ति के आधार पर दूसरी ओर deserialize। अर्थात। इसके लिए आपको कस्टम सीरिएलाइज़र को लागू करने की आवश्यकता है। –
तो बॉक्स से बाहर करने का कोई तरीका नहीं है। ठीक है, मदद के लिए धन्यवाद! – pbespechnyi