我有一个spring webservice,它返回一个json响应。我正在使用此处给出的示例来创建服务: http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/
返回json的格式为: { “名” 的空值, “staffName”:[ “KFC-金宝”, “史密斯”]}
我想从返回的响应中删除任何null对象,所以它看起来像这样: { “staffName”:[ “KFC-金宝”, “史密斯”]}
我在这里发现了类似的问题,但我已经能够找到解决方案,例如
Configuring ObjectMapper in Spring
configuring the jacksonObjectMapper not working in spring mvc 3
how to configure spring mvc 3 to not return "null" object in json response?
Spring configure @ResponseBody JSON format
Jackson+Spring3.0.5 custom object mapper
从阅读这些和其他来源,我认为实现我想要的最干净的方法是使用Spring 3.1和可以在mvc-annotation中配置的消息转换器。 我更新的spring配置文件是:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:component-scan base-package="com.mkyong.common.controller" />
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="prefixJson" value="true" />
<property name="supportedMediaTypes" value="application/json" />
<property name="objectMapper">
<bean class="org.codehaus.jackson.map.ObjectMapper">
<property name="serializationInclusion" value="NON_NULL"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
服务类与mkyong.com网站上的服务类相同,只是我注释了商店名称变量的设置,因此它是空的。
@Controller
@RequestMapping("/kfc/brands")
public class JSONController {
@RequestMapping(value="{name}", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public @ResponseBody Shop getShopInJSON(@PathVariable String name) {
Shop shop = new Shop();
//shop.setName(name);
shop.setStaffName(new String[]{name, "cronin"});
return shop;
}
}
我使用的杰克逊罐子是jackson-mapper-asl 1.9.0和jackson-core-asl 1.9.0。这是我添加到pom中的唯一新罐子,作为我从mkyong.com下载的spring-json项目的一部分提供。
项目构建成功,但是当我通过浏览器调用服务时,我仍然得到相同的东西,即 { “名” 的空值, “staffName”:[ “KFC-金宝”, “史密斯”]}
有谁能告诉我我的配置出错了?
我已经尝试了其他几个选项,但是我能够以正确的格式返回json的唯一方法是将Object mapper添加到JSONController并让“getShopInJSON”方法返回一个字符串,即
public @ResponseBody String getShopInJSON(@PathVariable String name) throws JsonGenerationException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
Shop shop = new Shop();
//shop.setName(name);
shop.setStaffName(new String[]{name, "cronin"});
String test = mapper.writeValueAsString(shop);
return test;
}
现在,如果我调用该服务,我会得到预期的 { “staffName”:[ “KFC-金宝”, “克罗宁”]}
我也能够使用@JsonIgnore注释使其工作,但此解决方案不适合我。
我不明白为什么它在代码中工作但在配置中没有,所以任何帮助都会很棒。
答案 0 :(得分:73)
自Jackson 2.0起,您可以使用JsonInclude
@JsonInclude(Include.NON_NULL)
public class Shop {
//...
}
答案 1 :(得分:53)
自从使用杰克逊以来,你必须将其配置为杰克逊的财产。对于Spring Boot REST服务,您必须在application.properties
或application.yml
中配置它:
spring.jackson.default-property-inclusion = NON_NULL
答案 2 :(得分:8)
@JsonInclude(Include.NON_NULL)
对于jackson 2.0或更高版本使用var weekDim = ndx.dimension(function(d) {
return d.date.substring(0,4) + "" + d.week;
});
这将删除空对象和空对象。
答案 3 :(得分:5)
如果您使用的是Jackson 2,则消息转换器标记为:
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="prefixJson" value="true"/>
<property name="supportedMediaTypes" value="application/json"/>
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="serializationInclusion" value="NON_NULL"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
答案 4 :(得分:5)
自Jackson 2.0起,@JsonSerialize(include = xxx)
已被弃用,转而使用@JsonInclude
答案 5 :(得分:4)
从版本1.6开始,我们有了新的注释JsonSerialize(例如版本1.9.9)。
示例:
@JsonSerialize(include=Inclusion.NON_NULL)
public class Test{
...
}
默认值为ALWAYS。
在旧版本中,您可以使用JsonWriteNullProperties,这在新版本中已弃用。 例如:
@JsonWriteNullProperties(false)
public class Test{
...
}
答案 6 :(得分:3)
对于所有非xml配置人员:
ObjectMapper objMapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
HttpMessageConverter msgConverter = new MappingJackson2HttpMessageConverter(objMapper);
restTemplate.setMessageConverters(Collections.singletonList(msgConverter));
答案 7 :(得分:1)
我通过配置Spring容器找到了解决方案,但它仍然不是我想要的。
我回滚到Spring 3.0.5,删除并在其中我将配置文件更改为:
<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>
<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_NULL</value>
</list>
</property>
</bean>
这当然类似于其他问题中的回答,例如:
configuring the jacksonObjectMapper not working in spring mvc 3
需要注意的重要一点是,mvc:annotation-driven和AnnotationMethodHandlerAdapter不能在同一个上下文中使用。
我仍然无法使用Spring 3.1和mvc:annotation-driven。使用mvc:annotation-driven的解决方案以及随之而来的所有好处我认为会好得多。如果有人能告诉我如何做到这一点,那就太好了。
答案 8 :(得分:1)
您可以将JsonWriteNullProperties
用于旧版本的Jackson。
对于Jackson 1.9+,请使用JsonSerialize.include
。
答案 9 :(得分:0)
设置spring.jackson.default-property-inclusion=non_null
选项是最简单的解决方案,并且效果很好。
但是,请注意,如果您在代码中的某个地方实现了WebMvcConfigurer,则该属性解决方案将无法工作,并且您将必须在代码中设置NON_NULL序列化,如下所示:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
// some of your config here...
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(objectMapper);
converters.add(jsonConverter);
}
}