codememo

기본 컨스트럭터가 없는 Jackson 서드파티 클래스

tipmemo 2023. 2. 22. 21:57
반응형

기본 컨스트럭터가 없는 Jackson 서드파티 클래스

잭슨을 이용해 Json과의 POJO를 읽고 쓰려고 합니다.현재 서드파티 수업을 제외한 모든 수업에서 사용할 수 있도록 설정을 완료했습니다.Json에서 읽으려고 하면 다음 오류가 나타납니다.

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type

Google에서 몇 번 빠르게 검색한 결과, 클래스에 기본 생성자가 필요하거나 기본 생성자를 주석으로 재정의해야 합니다.안타깝게도 이 오류가 발생한 클래스는 서드파티 라이브러리에서 가져온 것이며 해당 클래스에는 기본 생성자가 없기 때문에 코드를 덮어쓸 수 없습니다.

그래서 제 질문은 제가 할 수 있는 일이 있을까요? 아니면 운이 없는 건가요?

감사해요.

Jackson의 Mix-In 기능Creator 기능을 함께 사용할 수 있습니다.Mix-In 기능을 사용하면 원래 서드파티 코드에 주석을 달 필요가 없어지고 Creator 기능은 커스텀인스턴스 작성 메커니즘을 제공합니다.

커스터마이징을 진행하려면 커스텀 디시리얼라이저를 작성할 필요가 없습니다.

하나의 접근법은 인스턴스를 생성하는 커스텀을 구현하는 것입니다.이 접근법의 장점은 예를 들어 mixin에 대한 변경은 필요하지 않다는 것입니다.ObjectMapper.

이 클래스에서 매핑이 허용됩니다.JsonNode원하는 유형의 값을 나타냅니다.

생성자가 없는 형식

public class ThirdPartyType {
    private String stringProperty;

    private int intProperty;

    private Object[] arrayProperty;

    public ThirdPartyType(String a, int b, Object[] c) {
        this.stringProperty = a;
        this.intProperty = b;
        this.arrayProperty = c;
    }
    
    // Getters and setters go here
}

커스텀 디시리얼라이저

import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdNodeBasedDeserializer;

import java.io.IOException;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.StreamSupport;

public class ThirdPartyTypeDeserializer 
        extends StdNodeBasedDeserializer<ThirdPartyType> {
    protected ThirdPartyTypeDeserializer() {
        super(ThirdPartyType.class);
    }

    @Override
    public ThirdPartyType convert(JsonNode root, DeserializationContext ctxt)
            throws IOException {
        return new ThirdPartyType(
                root.get("stringProperty").asText(null),
                root.get("intProperty").asInt(),
                StreamSupport.stream(
                        Spliterators.spliteratorUnknownSize(
                                root.get("arrayProperty").elements(),
                                Spliterator.ORDERED),
                        false).toArray());
    }
}

서드파티 타입이 포함된 타입

public class EnclosingClass {
    @JsonDeserialize(using = ThirdPartyTypeDeserializer.class)
    private ThirdPartyType thirdPartyProperty;
    
    // Getters and setters go here
}

값을 검색하는 중

String json = "{\"thirdPartyProperty\": {"
        + "\"stringProperty\": \"A\", "
        + "\"intProperty\": 5, "
        + "\"arrayProperty\": [1, \"B\", false]"
        + "}}";
ObjectMapper objectMapper = new ObjectMapper();
EnclosingClass enclosingClass =
        objectMapper.readValue(json, EnclosingClass.class);

언급URL : https://stackoverflow.com/questions/11838039/jackson-3rd-party-class-with-no-default-constructor

반응형