복붙노트

[SPRING] 스프링 부트 2로 업그레이드 한 후 ObjectMapper가 기본 생성자없이 역 직렬화 할 수 없습니다.

SPRING

스프링 부트 2로 업그레이드 한 후 ObjectMapper가 기본 생성자없이 역 직렬화 할 수 없습니다.

나는 다음과 같은 DTO를 가지고있다.

@Value
public class PracticeResults {
    @NotNull
    Map<Long, Boolean> wordAnswers;
}

@Value
public class ProfileMetaDto {

    @NotEmpty
    String name;
    @Email
    String email;
    @Size(min = 5)
    String password;
}

@Value는 생성자를 생성하는 Lombok 주석입니다. 즉,이 클래스에는 인수가없는 생성자가 없습니다.

나는 Spring Boot 1.4.3을 사용했다. RELEASE와 ObjectMapper bean은 json으로부터 그러한 객체를 deserialize 할 수 있었다.

Spring Boot 2.0.0.M7로 업그레이드 한 후 예외가 발생했습니다 :

com.fasterxml.jackson.databind.exc.InvalidDefinitionException : PracticeResults의 인스턴스를 생성 할 수 없습니다 (기본 생성자와 같은 작성자가 없습니다) : 객체 값에서 역 직렬화 할 수 없습니다 (대리자 또는 속성 기반 작성자 없음).

봄 부팅 1.4.3에서 사용 된 잭슨 버전은 2.8.10이고 봄 부팅 2.0.0.M7에서는 2.9.2입니다.

Google에이 문제를 시도했지만 @JsonCreator 또는 @JsonProperty 만 사용하는 솔루션을 발견했습니다.

그렇다면 스프링 부트 1.4.3에서 작동하고 스프링 부트 2에서 실패하는 이유는 무엇입니까? 이전 버전과 같은 방식으로 동작하도록 bean을 구성 할 수 있습니까?

해결법

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

    1.Lombok 버전 1.16.20의 변경으로 인해 lombok.config 파일에 다음 속성을 설정해야합니다 (이 파일이 없으면 프로젝트 루트에 만들 수 있음).

    Lombok 버전 1.16.20의 변경으로 인해 lombok.config 파일에 다음 속성을 설정해야합니다 (이 파일이 없으면 프로젝트 루트에 만들 수 있음).

    lombok.anyConstructor.addConstructorProperties=true
    

    이것은 롬복 변경 로그 (https://projectlombok.org/changelog)에 설명되어 있습니다.

    그 후에 @Value는 Jackson이 다시 받아 들여야합니다.

    관련 GitHub 문제는 다음 페이지를 참조하십시오. https://github.com/rzwitserloot/lombok/issues/1563

  2. ==============================

    2.이 문제를 해결할 수있는 또 하나의 방법. spring boot 2에 기본적으로 포함되어있는 Jackson 매개 변수 이름 모듈을 사용하십시오. 이 후에 Jackson은 객체를 비 직렬화 할 수 있습니다. 하지만 객체에 속성이 두 개 이상인 경우에만 작동합니다. 단일 속성의 경우 다음 오류 메시지가 나타납니다.

    이 문제를 해결할 수있는 또 하나의 방법. spring boot 2에 기본적으로 포함되어있는 Jackson 매개 변수 이름 모듈을 사용하십시오. 이 후에 Jackson은 객체를 비 직렬화 할 수 있습니다. 하지만 객체에 속성이 두 개 이상인 경우에만 작동합니다. 단일 속성의 경우 다음 오류 메시지가 나타납니다.

    com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `SomeClassName` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
    

    다음 때문에

    Lombok에서이 문제를 처리하기 위해 다음 해결 방법을 사용했습니다.

    @Value
    @AllArgsConstructor(onConstructor = @__(@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)))
    class SomeClassName {...}
    
  3. ==============================

    3.나는 롬복 버전을 'org.projectlombok : lombok : 1.18.0'로 업그레이드했고, 그것은 나를 위해 일했다.

    나는 롬복 버전을 'org.projectlombok : lombok : 1.18.0'로 업그레이드했고, 그것은 나를 위해 일했다.

  4. from https://stackoverflow.com/questions/48330613/objectmapper-cant-deserialize-without-default-constructor-after-upgrade-to-spri by cc-by-sa and MIT license