Spring REST服务:如何配置删除json响应中的null对象



我有一个spring-webservice,它返回json响应。我使用这里给出的示例来创建服务:http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/

json返回的格式为:{"name":null,"staffName":["kfc kampar","smith"]}

我想从返回的响应中删除任何null对象,所以它看起来像这样:{"staffName":["kfc kampar","smith"]}

我在这里发现了类似的问题,但我已经找到了一个可行的解决方案,例如

在Spring 中配置ObjectMapper

如何在使用基于spring注释的配置时配置MappingJacksonHttpMessageConverter?

配置jacksonObjectMapper在spring mvc 3 中不起作用

如何将springmvc3配置为不返回";空";json响应中的对象?

Spring配置@ResponseBody JSON格式

Jackson+Spring3.0.5自定义对象映射器

通过阅读这些和其他来源,我发现实现我想要的最干净的方法是使用Spring3.1和可以在mvc注释中配置的消息转换器。我更新的春季配置文件是:

<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罐子是Jackson mapper asl 1.9.0和Jackson core asl 1.9.0。这些是我在pom中添加的唯一新jar,是我从mkyong.com下载的spring-json项目的一部分

项目构建成功,但当我通过浏览器调用服务时,我仍然会得到相同的东西,即。{"name":null,"staffName":["kfc kampar","smith"]}

有人能告诉我我的配置哪里出了问题吗?

我已经尝试了其他几种选项,但我能够以正确格式返回json的唯一方法是将Object映射器添加到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 kampar","cronin"]}

我也可以使用@JsonIgnore注释使其工作,但这个解决方案不适合我

我不明白为什么它在代码中工作,而在配置中却不工作,所以任何帮助都是非常棒的。

由于Jackson 2.0,您可以使用JsonInclude

@JsonInclude(Include.NON_NULL)
public class Shop {
//...
}

由于正在使用Jackson,您必须将其配置为Jackson属性。在Spring Boot REST服务的情况下,您必须在application.propertiesapplication.yml:中配置它

spring.jackson.default-property-inclusion = NON_NULL

@JsonSerialize(include=JsonSerialize.Inclusion.NON_EMPTY)
public class Shop {
//...
}

对于jackson 2.0或更高版本,请使用@JsonInclude(Include.NON_NULL)

这将删除空对象和null对象。

设置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);
}
}

如果您使用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>

自版本1.6以来,我们有了新的注释JsonSerialize(例如在版本1.9.9中)。

示例:

@JsonSerialize(include=Inclusion.NON_NULL)
public class Test{
...
}

默认值为ALWAYS。

在旧版本中,您可以使用JsonWriteNullProperties,这在新版本中是不推荐使用的。示例:

@JsonWriteNullProperties(false)
public class Test{
...
}

从Jackson 2.0开始,@JsonSerialize(include = xxx)已被弃用,取而代之的是@JsonInclude

对于所有非xml配置人员:

ObjectMapper objMapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
HttpMessageConverter msgConverter = new MappingJackson2HttpMessageConverter(objMapper);
restTemplate.setMessageConverters(Collections.singletonList(msgConverter));

您可以将JsonWriteNullProperties用于旧版本的Jackson。

对于Jackson 1.9+,请使用JsonSerialize.include

我通过配置Spring容器找到了一个解决方案,但它仍然不是我想要的。

我回滚到Spring3.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>

这当然类似于在其他问题中给出的回答,例如

配置jacksonObjectMapper在spring mvc 3 中不起作用

需要注意的是,mvc:annotation-driven和AnnotationMethodHandlerAdapter不能在同一上下文中使用。

尽管如此,我仍然无法让它与Spring3.1和mvc一起工作:注释驱动。我认为,一个使用mvc的解决方案:注释驱动以及随之而来的所有好处会更好。如果有人能教我怎么做,那就太好了。

最新更新