non_null jsoninclude java spring jackson

java - jsoninclude - Servicio REST de Spring: cómo configurar para eliminar objetos nulos en la respuesta json



java jackson ignore if null (9)

A partir de Jackson 2.0, @JsonSerialize(include = xxx) ha quedado en desuso en favor de @JsonInclude

Tengo un servicio web de primavera que devuelve una respuesta json. Estoy usando el ejemplo dado aquí para crear el servicio: http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/

El formato en el que se devuelve el json es: {"nombre": nulo, "staffName": ["kfc-kampar", "smith"]}

Quiero eliminar cualquier objeto nulo de la respuesta devuelta para que se vea así: {"staffName": ["kfc-kampar", "smith"]}

He encontrado preguntas similares aquí pero he podido lograr que una solución funcione, por ejemplo,

Configurando ObjectMapper en Spring

¿Cómo configurar MappingJacksonHttpMessageConverter mientras se usa la configuración basada en anotaciones de resorte?

la configuración del jacksonObjectMapper no funciona en spring mvc 3

¿Cómo configurar spring mvc 3 para no devolver el objeto "nulo" en la respuesta json?

Spring configura el formato @ResponseBody JSON

Jackson + Spring3.0.5 asignador de objetos personalizados

Al leer estas y otras fuentes, imaginé que la forma más limpia de lograr lo que quería era usar Spring 3.1 y los convertidores de mensajes que se pueden configurar dentro de la anotación mvc. Mi archivo de configuración de primavera actualizado es:

<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>

La clase de servicio es la misma que se da en el sitio mkyong.com, excepto que comenté la configuración de la variable Nombre de la tienda, por lo que es nula, es decir

@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; } }

Los tarros Jackson que estoy usando son jackson-mapper-asl 1.9.0 y jackson-core-asl 1.9.0. Estos son los únicos frascos nuevos que he agregado al pom, como parte del proyecto spring-json que descargué de mkyong.com.

El proyecto se compila con éxito, pero cuando invoco el servicio a través del navegador todavía obtengo lo mismo, es decir, {"nombre": nulo, "nombre del personal": ["kfc-kampar", "smith"]}

¿Alguien me puede decir dónde me equivoco con mi configuración?

He intentado varias otras opciones, pero la única forma en que he podido devolver el json en el formato correcto es agregar el Asignador de objetos al JSONController y hacer que el método "getShopInJSON" devuelva una cadena, es decir

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; }

Ahora, si invoco el servicio, obtengo el esperado, es decir, {"staffName": ["kfc-kampar", "cronin"]}

También he podido hacer que funcione con la anotación @JsonIgnore, pero esta solución no es adecuada para mí.

No entiendo por qué funciona en código pero no en la configuración, por lo que cualquier ayuda sería fantástica.


Dado que se está utilizando Jackson, debe configurarlo como una propiedad de Jackson. En el caso de los servicios REST de Spring Boot, debe configurarlo en application.properties :

spring.jackson.default-property-inclusion = NON_NULL

source


Desde Jackson 2.0 puedes usar JsonInclude

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


Desde la versión 1.6 tenemos una nueva anotación JsonSerialize (en la versión 1.9.9 por ejemplo).

Ejemplo:

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

El valor predeterminado es SIEMPRE.

En versiones anteriores puede usar JsonWriteNullProperties, que está en desuso en nuevas versiones. Ejemplo:

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


He encontrado una solución a través de la configuración del contenedor Spring, pero aún no es exactamente lo que quería.

Regresé a Spring 3.0.5, eliminé y en su lugar cambié mi archivo de configuración a:

<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>

Por supuesto, esto es similar a las respuestas dadas en otras preguntas, por ejemplo,

la configuración del jacksonObjectMapper no funciona en spring mvc 3

Lo importante a tener en cuenta es que mvc: annotation-driven y AnnotationMethodHandlerAdapter no se pueden usar en el mismo contexto.

Todavía no puedo hacer que funcione con Spring 3.1 y mvc: aunque con anotación. Una solución que utiliza mvc: anotación impulsada y todos los beneficios que la acompañan serían mucho mejores, creo. Si alguien pudiera mostrarme cómo hacer esto, sería genial.


Para todas las personas que no son de configuración XML:

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



Si está utilizando Jackson 2, la etiqueta de convertidores de mensajes es:

<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>


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

para jackson 2.0 o posterior use @JsonInclude(Include.NON_NULL)

Esto eliminará objetos vacíos y nulos.