불변 객체에서 Jackson InvalidDefinitionException을 해결하는 방법

실무에서 Spring 프레임워크로 작업하는 동안 변경 불가능한 객체가 있는 동안 웹 레이어 테스트 중에 InvalidDefinitionException이 발생하는 문제에 직면했습니다. 이는 Jackson이 기본적으로 인수 없는 생성자와 세터를 사용하여 JSON 페이로드에서 엔터티를 역직렬화한다는 사실 때문입니다. 그리고 분명히 이러한 관행은 잘못된 소프트웨어 설계로 이어집니다. 따라서 이 문제도 해결하고 싶다면 내 솔루션을 제공하겠습니다.

시작하려면 내 엔티티 모델을 살펴보겠습니다. 아래의 다음 코드 스니펫을 관찰하십시오.

@Value
@Document(collection = "customers")
public class CustomerModel {
    @Id String customerId;
    String companyName;
    String companyEmail;
    String taxId;
    AddressModel billingAddress;
    AddressModel shippingAddress;

}


여기에서 다음을 얻기 위해 여기에서 @Value 주석을 사용한다는 것을 알 수 있습니다.
  • 모든 인수 생성자
  • 모든 필드가 비공개 및 최종 필드임
  • 세터 없음

  • 애플리케이션의 웹 계층 내에서 이 엔터티 클래스를 사용하면 문제가 발생하지 않으며 예를 들어 외부 클라이언트로 API를 호출할 때 직렬화가 예상대로 작동합니다. 그러나 웹 레이어를 어설션하는 테스트를 작성할 때 예외로 끝낼 것입니다. 이미 말했듯이 Jackson은 인수 없는 생성자와 설정자 없이 JSON을 역직렬화할 수 없기 때문입니다.



    Stackoverflow에서 찾은 첫 번째 솔루션은 내 프로젝트의 루트에 다음 매개변수를 사용하여 lombok.config 파일을 만드는 것입니다.

    lombok.anyConstructor.addConstructorProperties=true
    


    그러나 이것은 문제를 해결하지 못했습니다. 그리고 여전히 이 게시물을 읽고 있다면 이 솔루션도 실패했음을 의미합니다. 작업 방식으로 찾은 것은 아래 코드 스니펫에 표시된 것처럼 모든 인수 생성자를 수동으로 생성하고 Jackson에 대해 주석을 추가하는 것입니다.

    @Value
    @Document(collection = "customers")
    public class CustomerModel {
    
        @Id String customerId;
        String companyName;
        String companyEmail;
        String taxId;
        AddressModel billingAddress;
        AddressModel shippingAddress;
    
        @JsonCreator
        public CustomerModel(
                @JsonProperty("customerId") String customerId, 
                @JsonProperty("companyName") String companyName, 
                @JsonProperty("companyEmail") String companyEmail, 
                @JsonProperty("taxId") String taxId, 
                @JsonProperty("billingAddress") AddressModel billingAddress, 
                @JsonProperty("shippingAddress") AddressModel shippingAddress) {
            this.customerId = customerId;
            this.companyName = companyName;
            this.companyEmail = companyEmail;
            this.taxId = taxId;
            this.billingAddress = billingAddress;
            this.shippingAddress = shippingAddress;
        }
    
    }
    


    기본적으로 여기서는 두 가지 주석을 사용합니다.

  • @JsonCreator는 역직렬화를 위해 Jackson이 명시적으로 사용할 생성자를 표시합니다
  • .

  • @JsonProperty는 Jackson의 액세스를 돕기 위해 생성자의 인수에 사용됩니다concrete fields in runtime.

  • 이 코드는 저에게 완벽하게 작동합니다. 그런데 중첩된 개체가 있는 경우에도 이러한 단계를 따르는 것을 잊지 마십시오. 그리고 그것이 당신에게도 도움이 되기를 바랍니다.

    해결 방법을 모르는 Spring Boot 관련 문제가 있는 경우 주저하지 말고 contact me 에 문의하십시오.

    좋은 웹페이지 즐겨찾기