Springconfiguration@ResponseBody JSON格式
想象一下我在Spring 3 @Controller中有这个注解的方法
@RequestMapping("") public @ResponseBody MyObject index(@RequestBody OtherObject obj) { MyObject result = ...; return result; }
但是我需要configuration输出json格式,就像我在做:
ObjectMapper om = new ObjectMapper(); om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, true); om.getSerializationConfig() .setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); om.getSerializationConfig() .set(SerializationConfig.Feature.INDENT_OUTPUT, false);
有什么办法来configuration这种行为?
我发现了一些相关的问题,但我不确定如何使它们适应我的具体情况:
- spring前缀与响应者
- 谁在Spring MVC中设置响应内容types(@ResponseBody)
谢谢 !
对于那些使用基于Java的Springconfiguration的人 :
@Configuration @ComponentScan(basePackages = "com.domain.sample") @EnableWebMvc public class SpringConfig extends WebMvcConfigurerAdapter { .... @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); final ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); converter.setObjectMapper(objectMapper); converters.add(converter); super.configureMessageConverters(converters); } .... }
我正在使用来自fasterxml的MappingJackson2HttpMessageConverter。
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.3.1</version> </dependency>
如果您想使用codehaus-jackson映射器,请使用这一个MappingJacksonHttpMessageConverter
<dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>${codehaus.jackson.version}</version> </dependency>
我想要解决一个非常类似的问题,那就是将Jackson Mapperconfiguration为“不要为了基督的目的而将null值序列化”。
我不想留下mvc:annotation-driven标签,所以我发现如何在不删除mvc:注解驱动的情况下configurationJackson的ObjectMapper,并且添加不是很花哨的ContentNegotiatingViewResolver。
美丽的是你不必自己写Java代码!
这里是XMLconfiguration(不要与Jackson类的不同命名空间混淆,我只是使用新的Jakson 2.x库…同样也应该与Jackson 1.x库一起工作):
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="com.fasterxml.jackson.databind.ObjectMapper"> <property name="serializationInclusion"> <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value> </property> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
愤怒的小丑指出我正确的方向。
这是我最终做的,以防万一有人发现它有用。
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="objectMapper" ref="jacksonObjectMapper" /> </bean> </list> </property> </bean> <!-- jackson configuration : https://stackoverflow.com/questions/3661769 --> <bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" /> <bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig" factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" /> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetObject" ref="jacksonSerializationConfig" /> <property name="targetMethod" value="setSerializationInclusion" /> <property name="arguments"> <list> <value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_DEFAULT</value> </list> </property> </bean>
我仍然需要弄清楚如何configuration其他属性,例如:
om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, true);
在spring3.2中,新的解决scheme是由http://static.springsource.org/spring/docs/3.2.0.BUILD-SNAPSHOT/api/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.html下面是我的例子:;
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"> <property name="featuresToEnable"> <array> <util:constant static-field="com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES" /> </array> </property> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
对于Spring 4.1.3+版本
我尝试了Jama的解决scheme,但是随后所有的响应都返回Content-type“application / json”,包括生成的主页面。
重载configureMessageConverters(...)
可以防止spring设置默认的转换器。 Spring 4.1.3允许通过覆盖 extendMessageConverters(...)
来修改已configuration的转换器 :
@Configuration public class ConverterConfig extends WebMvcConfigurerAdapter { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { for (HttpMessageConverter<?> converter : converters) { if (converter instanceof AbstractJackson2HttpMessageConverter) { AbstractJackson2HttpMessageConverter c = (AbstractJackson2HttpMessageConverter) converter; ObjectMapper objectMapper = c.getObjectMapper(); objectMapper.setSerializationInclusion(Include.NON_NULL); } } super.extendMessageConverters(converters); } }
请参阅
org.springframework..WebMvcConfigurationSupport#getMessageConverters()
请参阅
org.springframework..WebMvcConfigurationSupport#addDefaultHttpMessageConverters(...)
我写了自己的FactoryBean实例化一个ObjectMapper(简化版本):
public class ObjectMapperFactoryBean implements FactoryBean<ObjectMapper>{ @Override public ObjectMapper getObject() throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); return mapper; } @Override public Class<?> getObjectType() { return ObjectMapper.class; } @Override public boolean isSingleton() { return true; } }
以及在弹簧configuration中的用法:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="objectMapper" ref="jacksonObjectMapper" /> </bean> </list> </property> </bean>
不回答这个问题,但这是最好的谷歌结果。
如果有人来到这里,想为Spring 4做(就像我发生的那样),你可以使用注释
@JsonInclude(Include.NON_NULL)
在返回class上。
看看Rick Hightower的方法。 他的方法避免了将ObjectMapperconfiguration为单例,并允许您按照每个请求方法以不同的方式过滤相同对象的JSON响应。
http://www.jroller.com/RickHigh/entry/filtering_json_feeds_from_spring
您可以在Spring xml文件中将ObjectMapperconfiguration为一个bean。 对ObjectMapper的引用是MappingJacksonJsonView
类。 然后,您需要将视图附加到ViewResolver。
像这样的东西应该工作:
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="mediaTypes"> <map> <entry key="json" value="application/json" /> <entry key="html" value="text/html" /> </map> </property> <property name="viewResolvers"> <list> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> </list> </property> <property name="defaultViews"> <list> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"> <property name="prefixJson" value="false" /> <property name="objectMapper" value="customObjectMapper" /> </bean> </list> </property> </bean>
customObjectMapper
在xml文件中的其他地方定义。 请注意,你可以直接用Enums Jackson定义的Spring属性值来设置; 看到这个问题 。
此外,ContentNegotiatingViewResolver可能不是必需的,它只是我在现有项目中使用的代码。
是的,但是如果你开始使用mixins会发生什么情况,你不能将ObjectMapper作为一个singleton,因为你将会全局应用这个configuration。 那么你将在同一个ObjectMapper实例上添加或设置mixin类?
您可以执行以下操作(jackson版本<2):
自定义映射器类:
import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; import org.codehaus.jackson.map.annotate.JsonSerialize; public class CustomObjectMapper extends ObjectMapper { public CustomObjectMapper() { super.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, true); super.getSerializationConfig() .setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); super.getSerializationConfig() .set(SerializationConfig.Feature.INDENT_OUTPUT, false); } }
弹簧configuration:
<mvc:annotation-driven> <mvc:message-converters register-defaults="false"> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="objectMapper"> <bean class="package.CustomObjectMapper"/> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>