我有一个使用Spring (v4.0.5)的http服务。它的http端点是使用Spring Web MVC配置的。响应是基于模式生成的基于JAXB2的anotated类。响应被包装在JAXBElement中,因为生成的JAXB类没有使用@XmlRootElement注释(并且不能修改模式来修改它)。我不得不用fight a bit来让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-object:
{
"what": "what",
"when": "2014-06-09T15:56:46Z"
}下面是我的JSON编组配置( spring上下文配置的一部分):
<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>我希望这可以通过配置ObjectMapper来实现。我想,或者推出我自己的序列化程序可能会起作用。有什么想法?有什么建议吗?
发布于 2014-06-11 00:51:08
您可以为JAXBElement类注册一个mixin annotation,这将把@JsonValue注释放在JAXBElement.getValue()方法上,使其返回值成为JSON表示。下面是一个示例:
提供给xjc的.xsd chema文件示例。
<?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>一个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));
}
}输出:
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<item>
<number>123</number>
<string>value</string>
</item>
JSON:
{
"number" : 123,
"string" : "value"
}发布于 2014-06-23 04:36:32
有关完全配置的项目的示例,请参见:
在编组marshaling.
使用here。
最基本的部分是:
JSON
AnnotationIntrospectorPair introspector (请注意,该页面有点过时)。
将JAXB注解内省函数配置为主要内省函数(确保响应符合XSD规定),将Jackson注释内省函数配置为辅助函数(确保使用JAXBElement解包混合函数)。
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.
* <p>
* More on the usage and configuration options is available
* <a href="http://wiki.fasterxml.com/JacksonMixInAnnotations">here</a>.
*/
public interface JaxbElementMixin {
@JsonValue
Object getValue();
}Spring上下文配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd">
<context:component-scan base-package="io.github.gv0tch0.sotaro"/>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="ignoreAcceptHeader" value="false" />
<property name="useJaf" value="false" />
<property name="defaultContentType" value="application/xml" />
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml" />
<entry key="json" value="application/json" />
</map>
</property>
</bean>
<bean id="typeFactory" class="com.fasterxml.jackson.databind.type.TypeFactory" factory-method="defaultInstance" />
<bean id="jaxbIntrospector" class="com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector">
<constructor-arg ref="typeFactory" />
</bean>
<bean id="jacksonIntrospector" class="com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector" />
<bean id="annotationIntrospector" class="com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair">
<!-- Note that in order to get the best of both the JAXB annotation instrospector and the Mixin configuration
the JAXB introspector needs to be the primary introspector, hence it needs to stay at position 0. -->
<constructor-arg index="0" ref="jaxbIntrospector" />
<constructor-arg index="1" ref="jacksonIntrospector" />
</bean>
<bean id="jacksonMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="annotationIntrospector" ref="annotationIntrospector" />
<!-- The mixin ensures that when JAXBElement wrapped responses are marshalled as JSON the
JAXBElement "envelope" gets discarded (which makes our JSON responses conform to spec). -->
<property name="mixInAnnotations">
<map key-type="java.lang.Class" value-type="java.lang.Class">
<entry key="javax.xml.bind.JAXBElement" value="io.github.gv0tch0.sotaro.JaxbElementMixin" />
</map>
</property>
<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>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="jacksonMapper" />
<property name="supportedMediaTypes" value="application/json" />
</bean>
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="supportJaxbElementClass" value="true" />
<property name="contextPath" value="io.github.gv0tch0.sotaro" />
</bean>
<bean id="xmlConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<constructor-arg ref="jaxbMarshaller" />
<property name="supportedMediaTypes" value="application/xml" />
</bean>
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters register-defaults="false">
<ref bean="xmlConverter" />
<ref bean="jsonConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
</beans>https://stackoverflow.com/questions/24124149
复制相似问题