Я использую Spring Boot (1.2.1) аналогично тому, как в их руководстве по созданию веб-службы RESTful :
@RestController
public class EventController {
@RequestMapping("/events/all")
EventList events() {
return proxyService.getAllEvents();
}
}
Итак, Spring MVC неявно использует Jackson для сериализации моего EventList
объекта в JSON.
Но я хочу сделать несколько простых настроек формата JSON, например:
setSerializationInclusion(JsonInclude.Include.NON_NULL)
Вопрос в том, как проще всего настроить неявный преобразователь JSON?
Я пробовал подход , описанный в этом сообщении в блоге , создав CustomObjectMapper и так далее, но шаг 3, «Регистрация классов в контексте Spring», завершился неудачно:
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: {}
Похоже, что эти инструкции предназначены для более старых версий Spring MVC, а я ищу простой способ заставить это работать с последней версией Spring Boot.
Ответы:
Если вы используете Spring Boot 1.3, вы можете настроить включение сериализации с помощью
application.properties
:После изменений в Jackson 2.7 Spring Boot 1.4 использует
spring.jackson.default-property-inclusion
вместо этого свойство :spring.jackson.default-property-inclusion=non_null
См. Раздел « Настройка Jackson ObjectMapper » в документации Spring Boot.
Если вы используете более раннюю версию Spring Boot, самый простой способ настроить включение сериализации в Spring Boot - объявить собственный, соответствующим образом настроенный
Jackson2ObjectMapperBuilder
bean-компонент. Например:@Bean public Jackson2ObjectMapperBuilder objectMapperBuilder() { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.serializationInclusion(JsonInclude.Include.NON_NULL); return builder; }
источник
@ComponentScan
и@EnableAutoConfiguration
т.д.)?@Configuration
класс вашего приложения. ОсновнойApplication
класс - хорошее место для этого.Я немного поздно отвечаю на этот вопрос, но в будущем кому-то это может пригодиться. Приведенный ниже подход, помимо множества других, работает лучше всего, и я лично считаю, что он лучше подходит для веб-приложения.
@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())); } }
источник
WebMvcConfigurer
В свойствах приложения можно настроить многое. К сожалению, эта функция только в версии 1.3, но вы можете добавить в Config-Class
@Autowired(required = true) public void configureJackson(ObjectMapper jackson2ObjectMapper) { jackson2ObjectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); }
[ОБНОВЛЕНИЕ: вы должны работать с ObjectMapper, потому что
build()
-метод вызывается перед запуском конфигурации.]источник
В документации указано несколько способов сделать это.
источник
ObjectMapper
? Я имею в виду также оставить значение по умолчанию как обычное.Вы можете добавить в свой класс начальной загрузки следующий метод, помеченный как
@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; }
источник
spring.jackson.serialization-inclusion=non_null
раньше работал на насНо когда мы обновили версию Spring boot до 1.4.2.RELEASE или выше, она перестала работать.
Теперь другое свойство
spring.jackson.default-property-inclusion=non_null
творит чудеса.фактически
serialization-inclusion
устарел. Это то, что мне бросает мой интеллигент.Итак, начните использовать
spring.jackson.default-property-inclusion=non_null
вместоисточник
Я наткнулся на другое решение, которое довольно приятно.
По сути, выполните только шаг 2 из упомянутого блога и определите настраиваемый ObjectMapper как Spring
@Component
. (Все начало работать, когда я просто удалил все элементы AnnotationMethodHandlerAdapter с шага 3.)@Component @Primary public class CustomObjectMapper extends ObjectMapper { public CustomObjectMapper() { setSerializationInclusion(JsonInclude.Include.NON_NULL); configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } }
Работает, пока компонент находится в пакете, просканированном Spring. (С помощью
@Primary
В моем случае не обязательно, но почему бы не сделать это явным.)Для меня есть два преимущества по сравнению с другим подходом:
Jackson2ObjectMapperBuilder
.new CustomObjectMapper()
вместоnew ObjectMapper()
.источник
ObjectMapper
экземплярам, созданным или настроенным с помощью Spring Boot.@RestController
классах , которые в настоящее время достаточно для меня. (Вы имеете в виду, что эти экземпляры создаются Spring MVC, а не Spring Boot?) Но если я столкнусь с другими случаями, когда необходимо создать экземпляры ObjectMappers, я буду помнить о подходе Jackson2ObjectMapperBuilder!Когда я попытался сделать ObjectMapper основным в весенней загрузке 2.0.6, у меня возникли ошибки, поэтому я изменил ту, которую создал для меня весенняя загрузка.
Также см. Https://stackoverflow.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; }
источник
Я нашел решение, описанное выше:
spring.jackson.serialization -clusion = non_null
Для работы только начиная с версии spring boot 1.4.0.RELEASE. Во всех остальных случаях конфиг игнорируется.
Я проверил это, экспериментируя с модификацией образца пружинных ботинок "Spring-Boot-Sample-Jersey".
источник
Я знаю вопрос о загрузке Spring, но я считаю, что многие люди ищут, как это сделать при загрузке без Spring, например, я ищу почти весь день.
Выше Spring 4 нет необходимости настраивать,
MappingJacksonHttpMessageConverter
если вы собираетесь настраивать толькоObjectMapper
.Вам просто нужно сделать:
public class MyObjectMapper extends ObjectMapper { private static final long serialVersionUID = 4219938065516862637L; public MyObjectMapper() { super(); enable(SerializationFeature.INDENT_OUTPUT); } }
И в конфигурации Spring создайте этот bean-компонент:
@Bean public MyObjectMapper myObjectMapper() { return new MyObjectMapper(); }
источник