I'm trying to bind XML and JSON using the same JAXB annotations (using the JaxbAnnotationModule).
XML <--> JAXB <--> Jackson <--> JSON
I have to use the JAXB annotation and cannot alter them. My problem is that some XMLs convert to the generic class JAXBElement<T>
instead of a class T
directly. That leads to the JSON output:
{
"JAXBElement":{
"name":"{http://ift.tt/1Ah7mkZ",
"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
}
}
While I instead want:
{
"Capabilities":{
"ProcessOfferings":{ },
"Languages":{ },
"ServiceIdentification":{ },
"ServiceProvider":{ },
"OperationsMetadata":{ },
"version":"1.0.0",
"updateSequence":"1",
"service":"WPS",
"lang":"en-US"
}
}
The real object of type T
is wrapped by an JAXBElement. This may happen for some root elements and nested anywhere in the object tree as well. If I call getValue()
on that I'll get the real object. But I can't do this when the JAXBElement<T>
is not the root element since Jackson is the only interpreter between JAXB and JSON and I can neither alter the JAXB-Binding nor the created objects (some other parts of the code use them, too).
So what I found what might solve the problem are 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);
That solves the problem of the additional elements but causes the name of the object to be JAXBElement
instead of T
(in my case 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"
}
}
The questions:
Any idea what I can do (maybe annotate JAXBElementMixin<T>
) to get the correct type Capabilities
as object name (there are other classes instead of Capabilities
that can be placed as T
, too)?
Any other idea how to skip the serialization of any JAXBElement<T>
anywhere in the object tree and continue with the serialization of the object behind its getValue()
method?
Tiada ulasan:
Catat Ulasan