【发布时间】:2015-02-17 00:47:55
【问题描述】:
我正在尝试使用相同的 JAXB 注释(使用 JaxbAnnotationModule)绑定 XML 和 JSON。
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> 不是根元素时我不能这样做,因为杰克逊是 JAXB 和 JSON 之间的唯一解释器,我既不能改变 JAXB-Binding 也不能改变创建的对象(代码的其他部分使用它们,也)。
所以我发现可以解决问题的是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() 方法后面的对象的序列化?
【问题讨论】:
-
当您使用 WPS 时,您可能会对 ogc-schemas 项目感兴趣。
-
您能找到解决方案吗?
标签: java xml json jaxb jackson