RESTful 웹 서비스 구축 튜토리얼 에서와 비슷한 방식으로 Spring Boot (1.2.1)를 사용하고 있습니다.
@RestController
public class EventController {
@RequestMapping("/events/all")
EventList events() {
return proxyService.getAllEvents();
}
}
따라서 위의 Spring MVC는 EventList
JSON으로 객체 를 직렬화하기 위해 암시 적으로 Jackson을 사용합니다 .
하지만 다음과 같이 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
.
spring.jackson.serialization-inclusion=non_null
Jackson 2.7의 변경 사항에 따라 Spring Boot 1.4는 spring.jackson.default-property-inclusion
대신 이름이 지정된 속성을 사용합니다 .
spring.jackson.default-property-inclusion=non_null
Spring Boot 문서의 ” Customize the Jackson ObjectMapper “섹션을 참조하십시오 .
이전 버전의 Spring Boot를 사용하는 경우 Spring Boot에 직렬화 포함을 구성하는 가장 쉬운 방법은 적절하게 구성된 고유 한 Jackson2ObjectMapperBuilder
Bean 을 선언하는 것 입니다. 예를 들면 :
@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
return builder;
}
답변
나는이 질문에 조금 늦게 대답하고 있지만, 미래에 누군가가 유용하다고 생각할 것입니다. 아래의 접근 방식은 다른 많은 접근 방식 외에도 가장 잘 작동하며 개인적으로 웹 애플리케이션에 더 적합 할 것이라고 생각합니다.
@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()));
}
}
답변
응용 프로그램 속성에서 많은 것을 구성 할 수 있습니다. 불행히도이 기능은 버전 1.3에서만 가능하지만 Config-Class에 추가 할 수 있습니다.
@Autowired(required = true)
public void configureJackson(ObjectMapper jackson2ObjectMapper) {
jackson2ObjectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
[업데이트 : build()
구성이 실행되기 전에 -method가 호출 되므로 ObjectMapper에서 작업해야합니다 .]
답변
문서 에는이를 수행하는 여러 방법이 나와 있습니다.
기본값을
ObjectMapper
완전히 바꾸려면@Bean
해당 유형 의을 정의 하고로 표시하십시오@Primary
.결정적인
@Bean
유형은Jackson2ObjectMapperBuilder
기본적 모두 사용자 정의 할 수 있습니다ObjectMapper
와XmlMapper
(에 사용MappingJackson2HttpMessageConverter
하고MappingJackson2XmlHttpMessageConverter
각각을).
답변
주석이 달린 부트 스트랩 클래스 내부에 다음 메서드를 추가 할 수 있습니다. @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
우리를 위해 일했던
하지만 스프링 부트 버전을 1.4.2.RELEASE 이상으로 업그레이드했을 때 작동이 멈췄습니다.
자, 또 다른 속성 spring.jackson.default-property-inclusion=non_null
이 마술을하고 있습니다.
실제로 serialization-inclusion
는 더 이상 사용되지 않습니다. 이것이 내 intellij가 나에게 던지는 것입니다.
더 이상 사용되지 않음 : ObjectMapper.setSerializationInclusion은 Jackson 2.7에서 더 이상 사용되지 않습니다.
따라서 spring.jackson.default-property-inclusion=non_null
대신 사용 을 시작하십시오.
답변
나는 아주 좋은 또 다른 해결책을 우연히 발견했습니다.
기본적으로 언급 된 블로그에서 2 단계 만 수행 하고 사용자 정의 ObjectMapper를 Spring으로 정의합니다 @Component
. ( 3 단계에서 모든 AnnotationMethodHandlerAdapter 항목을 방금 제거 했을 때 상황이 작동하기 시작했습니다. )
@Component
@Primary
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
setSerializationInclusion(JsonInclude.Include.NON_NULL);
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
}
구성 요소가 Spring에서 스캔 한 패키지에있는 한 작동합니다. (사용@Primary
제 경우에는 이 필수는 아니지만 명시 적으로 만드는 것은 어떻습니까?)
저에게는 다른 접근 방식에 비해 두 가지 이점이 있습니다.
- 이것은 더 간단합니다. Jackson에서 클래스를 확장 할 수 있으며 .NET과 같은 Spring 관련 항목에 대해 알 필요가 없습니다
Jackson2ObjectMapperBuilder
. - 나는 내 응용 프로그램의 다른 부분에서 JSON을 deserialising 동일한 잭슨 CONFIGS를 사용하려면,이 방법은 매우 간단합니다 :
new CustomObjectMapper()
대신new ObjectMapper()
.