multiple jsonvalue jsonrawvalue jsonproperty jackson2objectmapperbuilder annotation java spring spring-mvc jackson spring-boot

java - jsonvalue - spring boot jackson2objectmapperbuilder



¿Cómo personalizar el mapeador Jackson JSON utilizado implícitamente por Spring Boot? (10)

Conozco la pregunta que pide el arranque de Spring, pero creo que muchas personas buscan cómo hacer esto en un arranque que no es Spring, como yo buscando casi todo el día.

Por encima del Spring 4, no es necesario configurar MappingJacksonHttpMessageConverter si solo tiene la intención de configurar ObjectMapper .

Solo necesitas hacer:

public class MyObjectMapper extends ObjectMapper { private static final long serialVersionUID = 4219938065516862637L; public MyObjectMapper() { super(); enable(SerializationFeature.INDENT_OUTPUT); } }

Y en su configuración de Spring, cree este bean:

@Bean public MyObjectMapper myObjectMapper() { return new MyObjectMapper(); }

Estoy usando Spring Boot (1.2.1), de manera similar a su tutorial de Creación de un servicio web RESTful :

@RestController public class EventController { @RequestMapping("/events/all") EventList events() { return proxyService.getAllEvents(); } }

Entonces, Spring MVC utiliza implícitamente Jackson para serializar mi objeto EventList en JSON.

Pero quiero hacer algunas personalizaciones simples para el formato JSON, como:

setSerializationInclusion(JsonInclude.Include.NON_NULL)

La pregunta es, ¿cuál es la forma más sencilla de personalizar el mapeador JSON implícito?

Probé el enfoque en esta publicación de blog , creando un CustomObjectMapper, etc., pero el paso 3, "Registrar clases en el contexto de Spring", falla:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name ''jacksonFix'': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.acme.project.JacksonFix.setAnnotationMethodHandlerAdapter(org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

Parece que esas instrucciones son para versiones anteriores de Spring MVC, mientras que estoy buscando una manera simple de hacer que esto funcione con Spring Boot más reciente.


Cuando traté de hacer ObjectMapper primario en spring boot 2.0.6 obtuve errores, así que modifiqué el que Spring Boot me creó

Consulte también https://.com/a/48519868/255139

@Lazy @Autowired ObjectMapper mapper; @PostConstruct public ObjectMapper configureMapper() { mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true); mapper.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, true); mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true); SimpleModule module = new SimpleModule(); module.addDeserializer(LocalDate.class, new LocalDateDeserializer()); module.addSerializer(LocalDate.class, new LocalDateSerializer()); mapper.registerModule(module); return mapper; }


Encontré la solución descrita anteriormente con:

spring.jackson.serialization-inclusive = non_null

Para trabajar solo a partir de la versión 1.4.0.RELEASE de spring boot. En todos los demás casos, la configuración se ignora.

Verifiqué esto experimentando con una modificación de la muestra de arranque de primavera "spring-boot-sample-jersey"


Estoy respondiendo un poco tarde a esta pregunta, pero alguien, en el futuro, podría encontrar esto útil. El siguiente enfoque, además de muchos otros enfoques, funciona mejor, y personalmente creo que sería mejor para una aplicación web.

@Autowired(required = true) public void configureJackson(ObjectMapper jackson2ObjectMapper) { jackson2ObjectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); }


Me topé con otra solución, que es bastante agradable.

Básicamente, solo realice el paso 2 del blog publicado mencionado y defina un ObjectMapper personalizado como Spring @Component . (Las cosas comenzaron a funcionar cuando eliminé todo el material AnnotationMethodHandlerAdapter del paso 3.)

@Component @Primary public class CustomObjectMapper extends ObjectMapper { public CustomObjectMapper() { setSerializationInclusion(JsonInclude.Include.NON_NULL); configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } }

Funciona mientras el componente esté en un paquete escaneado por Spring. (Usar @Primary no es obligatorio en mi caso, pero ¿por qué no hacer las cosas explícitas?)

Para mí hay dos beneficios en comparación con el otro enfoque:

  • Esto es mas simple; Solo puedo extender una clase de Jackson y no necesito saber cosas muy específicas de Spring como Jackson2ObjectMapperBuilder .
  • Quiero usar las mismas configuraciones de Jackson para deserializar JSON en otra parte de mi aplicación, y de esta manera es muy simple: new CustomObjectMapper() lugar de new ObjectMapper() .

Puede agregar un siguiente método dentro de su clase bootstrap que se anota con @SpringBootApplication

@Bean @Primary public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false); objectMapper.registerModule(new JodaModule()); return objectMapper; }


Se pueden configurar muchas cosas en las propiedades de la aplicación. Desafortunadamente, esta característica solo se encuentra en la Versión 1.3, pero puede agregar una Clase de configuración

@Configuration @EnableWebMvc public class WebConfiguration extends WebMvcConfigurerAdapter { ... other configurations @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.serializationInclusion(JsonInclude.Include.NON_NULL); builder.propertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); builder.serializationInclusion(Include.NON_EMPTY); builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd")); converters.add(new MappingJackson2HttpMessageConverter(builder.build())); converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())); } }

[ACTUALIZACIÓN: debe trabajar en ObjectMapper porque se llama al método build() antes de ejecutar la configuración.]


Si está utilizando Spring Boot 1.3, puede configurar la inclusión de serialización a través de application.properties :

spring.jackson.serialization-inclusion=non_null

Después de los cambios en Jackson 2.7, Spring Boot 1.4 usa una propiedad llamada spring.jackson.default-property-inclusion en spring.jackson.default-property-inclusion lugar:

spring.jackson.default-property-inclusion=non_null

Consulte la sección " Personalizar el Jackson ObjectMapper " en la documentación de Spring Boot.

Si está utilizando una versión anterior de Spring Boot, la forma más fácil de configurar la inclusión de serialización en Spring Boot es declarar su propio bean Jackson2ObjectMapperBuilder configurado Jackson2ObjectMapperBuilder . Por ejemplo:

@Bean public Jackson2ObjectMapperBuilder objectMapperBuilder() { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.serializationInclusion(JsonInclude.Include.NON_NULL); return builder; }


La documentación establece varias formas de hacer esto.

Si desea reemplazar completamente el ObjectMapper predeterminado, defina un @Bean de ese tipo y @Primary como @Primary .

La definición de un @Bean de tipo Jackson2ObjectMapperBuilder le permitirá personalizar tanto ObjectMapper como XmlMapper (utilizados en MappingJackson2HttpMessageConverter y MappingJackson2XmlHttpMessageConverter respectivamente).


spring.jackson.serialization-inclusion=non_null solía trabajar para nosotros

Pero cuando actualizamos la versión de arranque de primavera a 1.4.2.RELEASE o superior, dejó de funcionar.

Ahora, otra propiedad spring.jackson.default-property-inclusion=non_null está haciendo la magia.

de hecho, la serialization-inclusion está en desuso. Esto es lo que me arroja mi inteligencia.

En desuso: ObjectMapper.setSerializationInclusion fue en desuso en Jackson 2.7

Entonces, comience a usar spring.jackson.default-property-inclusion=non_null en spring.jackson.default-property-inclusion=non_null lugar