복붙노트

[SPRING] Spring Boot에서 암시 적으로 사용하는 Jackson JSON 매퍼를 사용자 정의하는 방법은 무엇입니까?

SPRING

Spring Boot에서 암시 적으로 사용하는 Jackson JSON 매퍼를 사용자 정의하는 방법은 무엇입니까?

나는 RESTful 웹 서비스 튜토리얼을 구축하는 것과 비슷한 방식으로 Spring Boot (1.2.1)를 사용하고있다.

@RestController
public class EventController {

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

}

그래서 위의 Spring MVC는 내 EventList 객체를 JSON으로 serialize하기 위해 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로 작업 할 수있는 간단한 방법을 찾고 있습니다.

해결법

  1. ==============================

    1.Spring Boot 1.3을 사용하는 경우 application.properties를 통해 직렬화 포함을 구성 할 수 있습니다.

    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 부트 문서의 "Jackson ObjectMapper 사용자 정의"섹션을 참조하십시오.

    이전 버전의 Spring Boot를 사용하고 있다면 Spring Boot에서 직렬화 포함을 구성하는 가장 쉬운 방법은 적절하게 구성된 Jackson2ObjectMapperBuilder bean을 선언하는 것이다. 예 :

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

    2.응용 프로그램 속성에서 많은 것들을 구성 할 수 있습니다. 불행하게도이 기능은 버전 1.3에만 있지만 구성 클래스에 추가 할 수 있습니다

    응용 프로그램 속성에서 많은 것들을 구성 할 수 있습니다. 불행하게도이 기능은 버전 1.3에만 있지만 구성 클래스에 추가 할 수 있습니다

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

    [업데이트 : config가 실행되기 전에 build () - 메소드가 호출되기 때문에 ObjectMapper에서 작업해야합니다.]

  3. ==============================

    3.나는이 질문에 조금 늦게 대답하고있다. 그러나 누군가는 미래에 이것을 유용하게 생각할 것이다. 아래의 접근 방식은 다른 접근 방식 외에도 가장 잘 작동하며 개인적으로 웹 응용 프로그램에 더 적합하다고 개인적으로 생각합니다.

    나는이 질문에 조금 늦게 대답하고있다. 그러나 누군가는 미래에 이것을 유용하게 생각할 것이다. 아래의 접근 방식은 다른 접근 방식 외에도 가장 잘 작동하며 개인적으로 웹 응용 프로그램에 더 적합하다고 개인적으로 생각합니다.

    @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()));
        }
    }
    
  4. ==============================

    4.이 문서에는 여러 가지 방법이 나와 있습니다.

    이 문서에는 여러 가지 방법이 나와 있습니다.

  5. ==============================

    5.spring.jackson.serialization-inclusion = non_null은 우리를 위해 일하는 데 사용됩니다.

    spring.jackson.serialization-inclusion = non_null은 우리를 위해 일하는 데 사용됩니다.

    그러나 스프링 부트 버전을 1.4.2.RELEASE 이상으로 업그레이드했을 때 작동이 멈췄습니다.

    이제 다른 속성 인 spring.jackson.default-property-inclusion = non_null이 마법을 수행하고 있습니다.

    실제로 serialization-inclusion은 더 이상 사용되지 않습니다. 이것이 내 인텔리가 내게 던지는 것입니다.

    따라서 대신 spring.jackson.default-property-inclusion = non_null을 사용하십시오.

  6. ==============================

    6.나는 다른 솔루션을 우연히 만났습니다. 아주 좋습니다.

    나는 다른 솔루션을 우연히 만났습니다. 아주 좋습니다.

    기본적으로 언급 된 블로그에서 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를 사용하는 것은 필수 사항이 아니지만 명시 적으로 명시하지 않는 것이 좋습니다.)

    나를 위해 다른 접근법에 비해 두 가지 이점이 있습니다.

  7. ==============================

    7.@SpringBootApplication 주석이 달린 부트 스트랩 클래스 내에 다음 메소드를 추가 할 수 있습니다.

    @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;
    }
    
  8. ==============================

    8.위에서 설명한 솔루션을 찾았습니다.

    위에서 설명한 솔루션을 찾았습니다.

    spring.jackson.serialization-inclusion = non_null

    1.4.0.RELEASE 버전의 스프링 부트에서만 작동합니다. 다른 모든 경우에는 config가 무시됩니다.

    나는 이것을 봄 부트 샘플 "spring-boot-sample-jersey"

  9. ==============================

    9.나는 스프링 부트를 묻는 질문을 알고 있지만, 나는 거의 하루 종일 검색하는 것 같은 비 스프링 부팅에서 이것을하는 방법을 찾는 많은 사람들이 있다고 믿는다.

    나는 스프링 부트를 묻는 질문을 알고 있지만, 나는 거의 하루 종일 검색하는 것 같은 비 스프링 부팅에서 이것을하는 방법을 찾는 많은 사람들이 있다고 믿는다.

    Spring 4 이상에서는 ObjectMapper 만 구성하려는 경우 MappingJacksonHttpMessageConverter를 구성 할 필요가 없습니다.

    당신은 단지해야 할 일 :

    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();
    }
    
  10. from https://stackoverflow.com/questions/28324352/how-to-customise-the-jackson-json-mapper-implicitly-used-by-spring-boot by cc-by-sa and MIT license