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

gv0*_*ch0 5 java spring json jackson jaxbelement

我有一个使用Spring(v4.0.5)的http服务.它的http端点是使用Spring Web MVC配置的.响应是由模式生成的JAXB2-anotated类.响应被包装在内,JAXBElement因为生成的JAXB类没有运动@XmlRootElement注释(并且模式不能修改为医生).我不得不打了一下有越来越XML编组TI工作; 无论如何,它正在发挥作用.

现在我正在设置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"
  }
}
Run Code Online (Sandbox Code Playgroud)

我想要编组的只是 - 对象value:

{
  "what": "what",
  "when": "2014-06-09T15:56:46Z"
}
Run Code Online (Sandbox Code Playgroud)

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

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
  <property name="objectMapper" ref="jacksonMapper" />
  <property name="supportedMediaTypes" value="application/json" />
</bean>

<bean id="jacksonMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
  <property name="dateFormat">
    <bean class="java.text.SimpleDateFormat">
      <constructor-arg type="java.lang.String" value="yyyy-MM-dd'T'HH:mm:ss'Z'" />
      <property name="timeZone">
        <bean class="java.util.TimeZone" factory-method="getTimeZone">
          <constructor-arg type="java.lang.String" value="UTC" />
        </bean>
      </property>
    </bean>
  </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*lov 10

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

给出的示例.xsd chema文件xjc.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="item" type="Thing"/>

    <xs:complexType name="Thing">
        <xs:sequence>
            <xs:element name="number" type="xs:long"/>
            <xs:element name="string" type="xs:string" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>

</xs:schema>
Run Code Online (Sandbox Code Playgroud)

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<Thing> 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));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<item>
    <number>123</number>
    <string>value</string>
</item>
JSON:
{
  "number" : 123,
  "string" : "value"
}
Run Code Online (Sandbox Code Playgroud)