想象一下,我在Spring 3 @Controller中有这个带注释的方法
@RequestMapping("")
public @ResponseBody MyObject index(@RequestBody OtherObject obj) {
MyObject result = ...;
return result;
}
但我需要配置输出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);
有没有办法配置这种行为?
我发现了几个相关问题,但我不确定如何根据具体情况调整它们:
答案 0 :(得分:31)
对于使用基于Java的Spring配置的人:
@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);
}
....
}
我正在使用MappingJackson2HttpMessageConverter
- 来自fastxml。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.1</version>
</dependency>
如果您想使用codehaus-jackson mapper,请使用此MappingJacksonHttpMessageConverter
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${codehaus.jackson.version}</version>
</dependency>
答案 1 :(得分:28)
我需要解决非常类似的问题,即将Jackson Mapper配置为“不要为基督的缘故序列化空值!!!”。
我不想留下花哨的mvc:annotation-driven标签,所以我发现,如何配置Jackson的ObjectMapper而不删除mvc:annotation-driven并添加不太真实的ContentNegotiatingViewResolver。
美妙的是你不必自己编写任何Java代码!
这是XML配置(不要与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>
答案 2 :(得分:15)
AngerClown pointed me向正确的方向发展。
这是我最终做的,以防有人发现它有用。
<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>
我仍然需要弄清楚如何配置其他属性,例如:
om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, true);
答案 3 :(得分:10)
在spring3.2中,新的解决方案由: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>
答案 4 :(得分:10)
对于Spring版本4.1.3 +
我尝试了Jama的解决方案,但随后所有回复都返回了Content-type'application / json',包括主要生成的HTML页面。
覆盖configureMessageConverters(...)
可阻止spring设置默认转换器。 Spring 4.1.3允许通过覆盖修改已配置的转换器 extendMessageConverters(...)
:
@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(...)
答案 5 :(得分:4)
我编写了自己的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;
}
}
弹簧配置中的用法:
<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>
答案 6 :(得分:4)
不回答问题,但这是google的最佳结果。
如果有人来到这里并且希望在春季4(就像它发生在我身上)那样做,你可以使用注释
@JsonInclude(Include.NON_NULL)
返回班级。
答案 7 :(得分:3)
看看Rick Hightower的方法。他的方法避免将ObjectMapper配置为单例,并允许您按照每种请求方法以不同的方式过滤同一对象的JSON响应。
http://www.jroller.com/RickHigh/entry/filtering_json_feeds_from_spring
答案 8 :(得分:2)
您可以将ObjectMapper配置为Spring xml文件中的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属性值;见this question。
此外,ContentNegotiatingViewResolver可能不是必需的,它只是我在现有项目中使用的代码。
答案 9 :(得分:1)
是的但是如果你开始使用mixins会发生什么,你不能将ObjectMapper作为单例,因为你将全局应用配置。那么您将在同一个ObjectMapper实例上添加或设置mixin类?
答案 10 :(得分:1)
您可以执行以下操作(jackson版本&lt; 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);
}
}
Spring config:
<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>