I'm trying to bind XML and JSON using the same JAXB annotations (using the JaxbAnnotationModule).
我正在尝试使用相同的JAXB注释绑定XML和JSON(使用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:
我必须使用JAXB注释,不能改变它们。我的问题是一些XML直接转换为泛型类JAXBElement
{
"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
}
}
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).
类型T的真实对象由JAXBElement包装。对于某些根元素可能会发生这种情况,并且嵌套在对象树中的任何位置。如果我调用getValue(),我将获得真实的对象。但是当JAXBElement
So what I found what might solve the problem are MixIns:
所以我发现可能解决问题的是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而不是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"
}
}
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)?
知道我能做什么(可能注释JAXBElementMixin
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?
还有其他想法如何在对象树中的任何地方跳过任何JAXBElement
2 个解决方案
#1
0
This is not directly an answer to your question, but possibly a recipe to achieve your goal.
这不是您问题的直接答案,但可能是实现目标的方法。
If you just want to get rid of the topmost JAXBElement
, why don't you just customize XJC to generate an additional class for your Capabilities
element?
如果你只想摆脱最顶层的JAXBElement,为什么不定制XJC为你的Capabilities元素生成一个额外的类?
Something like:
就像是:
<jaxb:bindings node="xs:element[@name='Capabilities']">
<jaxb:class name="Capabilities"/>
</jaxb:bindings>
This should generate a class Capabilities
annotated with '@XmlRootElement'. Thus you'll get rid of the JAXBElement
.
这应该生成一个用'@XmlRootElement'注释的类功能。因此,您将摆脱JAXBElement。
#2
0
Jackson does not support JAXBElement
, as it is very much XML-specific and is difficult to make work with other formats: Jackson JAXB support is focused on using information from annotations to make things work, but goal is not to be a full JAXB implementation.
Jackson不支持JAXBElement,因为它非常特定于XML并且很难与其他格式一起工作:Jackson JAXB支持专注于使用注释中的信息来使事情有效,但目标不是完整的JAXB实现。
As such your best bet is to do what @lexicore suggests and try to avoid use of JAXBElement
.
因此,最好的办法是做@lexicore建议并尝试避免使用JAXBElement。
#1
0
This is not directly an answer to your question, but possibly a recipe to achieve your goal.
这不是您问题的直接答案,但可能是实现目标的方法。
If you just want to get rid of the topmost JAXBElement
, why don't you just customize XJC to generate an additional class for your Capabilities
element?
如果你只想摆脱最顶层的JAXBElement,为什么不定制XJC为你的Capabilities元素生成一个额外的类?
Something like:
就像是:
<jaxb:bindings node="xs:element[@name='Capabilities']">
<jaxb:class name="Capabilities"/>
</jaxb:bindings>
This should generate a class Capabilities
annotated with '@XmlRootElement'. Thus you'll get rid of the JAXBElement
.
这应该生成一个用'@XmlRootElement'注释的类功能。因此,您将摆脱JAXBElement。
#2
0
Jackson does not support JAXBElement
, as it is very much XML-specific and is difficult to make work with other formats: Jackson JAXB support is focused on using information from annotations to make things work, but goal is not to be a full JAXB implementation.
Jackson不支持JAXBElement,因为它非常特定于XML并且很难与其他格式一起工作:Jackson JAXB支持专注于使用注释中的信息来使事情有效,但目标不是完整的JAXB实现。
As such your best bet is to do what @lexicore suggests and try to avoid use of JAXBElement
.
因此,最好的办法是做@lexicore建议并尝试避免使用JAXBElement。