2017-12-01 26 views
1

Jackson은 2.6.5에서 다음 클래스에 대해 json을 직렬화 해제 할 수 있지만 2.8.8에서는 실패합니다.lombok에서 생성 된 기본값이 아닌 생성자로 인해 잭슨 직렬화가 실패 함

모델 :

public static class Parent { 
    public long id; 
    public List<Child> children; 
} 

@RequiredArgsConstructor 
public static class Child { 
    public long childId; 

    @NonNull 
    @JsonIgnore 
    public Parent parent; 

    public Child() { } 
} 

JSON :

{ 
    "id": 1, 
    "children": [ 
    { 
     "childId": 2 
    } 
    ] 
} 

예외는 다음과 같습니다

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "childId" (class Parent), not marked as ignorable (2 known properties: "children", "id"]) 

나는 롬복에 의해 생성 된 자식 생성자가이 오류의 원인이되는 것으로 나타났습니다. 내가 롬복 주석을 없애거나 수동으로 생성자를 생성하면이 일이 멈추게됩니다. 어쨌든, 그것은 no-args Child() 생성자를 사용해야합니다. 이 문제의 원인은 무엇입니까?

답변

2

롬복 (Lombok)은 생성 된 생성자에 이라는 주석을 추가합니다. Jackson 2.8.8에서는 생성자가 "위임자 작성자"로 취급됩니다.

대리인 작성자는 Jackson이 한 유형의 객체에 대해 json을 다른 유형의 Java 객체로 비 직렬화 할 수 있도록 허용합니다.

lombok이 생성자를 생성하기 때문에 @ConstructorProperties({"parent"}) Child(Parent parent) {...} 잭슨은 자식 json을 부모 개체로 역 직렬화하려고 시도하고 자식을 생성하기 위해 생성자에 전달할 수 있습니다. 그런 다음 childId가 Parent의 필드가 아니기 때문에 예외가 발생합니다.

한 가지 해결 방법은 ObjectMapper 사용자 지정 JacksonAnnotationIntrospector으로 JSON을 deserialize하는 데 사용하도록 구성하여 생성자를 대리인 작성자로 해석하지 않도록하는 것입니다.

ObjectMapper objectMapper = new ObjectMapper(); 
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector().setConstructorPropertiesImpliesCreator(false)); 
+0

내 생각에, 당신 말이 맞아요. 어노테이션 매개 변수'suppressConstructorProperties'가 있었지만 오래 전에 사라졌습니다. – maaartinus

+1

'lombok.anyConstructor.suppressConstructorProperties = true'를 사용하여'lombok.config' 파일에서 해제 할 수 있습니다. 우리는 jdk9에서 다른 모듈에 대한 의존성이 필요하기 때문에 기본값을 만드는 것을 고려하고 있습니다. –