如何在没有JAXBElement包装的情况下JSON-marshal JAXBElement包装的响应?

我有一个使用Spring(v4.0.5)的http服务。 它的http端点是使用Spring Web MVC配置的。 响应是由模式生成的JAXB2-anotated类。 响应包装在JAXBElement因为生成的JAXB类没有运行@XmlRootElement注释(并且架构无法修改为医生)。 我不得不通过XML编组来解决这个问题。 无论如何,它正在发挥作用。

现在我正在设置JSON编组。 我遇到的是获取具有JAXBElement “信封”的JSON文档。

 { "declaredType": "io.github.gv0tch0.sotaro.SayWhat", "globalScope": true, "name": "{urn:io:github:gv0tch0:sotaro}say", "nil": false, "scope": "javax.xml.bind.JAXBElement$GlobalScope", "typeSubstituted": false, "value": { "what": "what", "when": "2014-06-09T15:56:46Z" } } 

我想要编组的只是value

 { "what": "what", "when": "2014-06-09T15:56:46Z" } 

这是我的JSON编组配置(弹簧上下文配置的一部分):

                 

我希望通过配置ObjectMapper可以实现这一点。 我想也可以推出我自己的序列化器。 思考? 建议?

您可以为JAXBElement类注册mixin注释 ,该类将@JsonValue注释放在JAXBElement.getValue()方法上,使其返回值为JSON表示。 这是一个例子:

xjc的示例.xsd chema文件。

           

Java主类:

 public class JacksonJAXBElement { // a mixin annotation that overrides the handling for the JAXBElement public static interface JAXBElementMixin { @JsonValue Object getValue(); } public static void main(String[] args) throws JAXBException, JsonProcessingException { ObjectFactory factory = new ObjectFactory(); Thing thing = factory.createThing(); thing.setString("value"); thing.setNumber(123); JAXBElement orderJAXBElement = factory.createItem(thing); System.out.println("XML:"); JAXBContext jc = JAXBContext.newInstance(Thing.class); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(orderJAXBElement, System.out); System.out.println("JSON:"); ObjectMapper mapper = new ObjectMapper(); mapper.addMixInAnnotations(JAXBElement.class, JAXBElementMixin.class); System.out.println(mapper.writerWithDefaultPrettyPrinter() .writeValueAsString(orderJAXBElement)); } } 

输出:

 XML:   123 value  JSON: { "number" : 123, "string" : "value" } 

有关完全配置的项目的示例:

  • 仅使用Spring(v4.0.5)进行内容协商和编组。
  • 使用JAXB生成响应的对象表示。
  • 支持XML和JSON内容协商。
  • 在编组JSON响应时,尊重JAXB注释。
  • 避免在响应对象周围泄漏JAXBElement -wrapper。

来到这里 。

必不可少的部分是:

  • 一个Jackson mixin ,它允许Jackson在编组之前从JAXBElement -wrapper中解包响应对象。
  • Spring上下文配置,它配置JSON对象映射器以使用Jackson,并配置所述映射器以利用mixin并使用AnnotationIntrospectorPair introspector (请注意页面有点过时),它将JAXB注释introspector配置为主要的introspector (确保响应符合XSD规定的内容)和Jackson作为次要内容(确保JAXBElement展开mixin正在播放中)。

Mixin

 /** * Ensures, when the Jackson {@link ObjectMapper} is configured with it, that * {@link JAXBElement}-wrapped response objects when serialized as JSON documents * do not feature the JAXBElement properties; but instead the JSON-document that * results in marshalling the member returned by the {@link JAXBElement#getValue()} * call. * 

* More on the usage and configuration options is available * here. */ public interface JaxbElementMixin { @JsonValue Object getValue(); }

Spring上下文配置