programing

Jackson JSON 라이브러리: 추상 필드를 포함하는 클래스를 인스턴스화하는 방법

fastcode 2023. 3. 31. 22:52
반응형

Jackson JSON 라이브러리: 추상 필드를 포함하는 클래스를 인스턴스화하는 방법

JSON 문자열을 java 객체로 변환하고 싶은데 이 객체의 클래스에 추상 필드가 포함되어 있어 잭슨은 이를 인스턴스화할 수 없고 객체를 생성할 수 없습니다.추상 클래스의 기본 구현에 대해 설명하는 가장 쉬운 방법은 무엇입니까?

setDefault(AbstractAnimal.class, Cat.class);

또는 JSON Atribute 이름을 기반으로 구현 클래스를 결정합니다(예: JSON 객체의 경우:

{
    ...
    cat: {...}
    ...
}

난 그냥 기다린다:

setImpl("cat", Cat.class);


Jackson에서 JSON에 클래스 정보를 삽입할 수 있다는 것은 알지만, 사용하는 JSON 형식을 복잡하게 만들고 싶지 않습니다.기본 구현 클래스를 설정하거나 XStream 라이브러리와 같이 속성 이름('cat')을 사용하여 사용할 클래스를 결정합니다.

xStream.alias("cat", Cat.class);

특히 한 줄에서 그렇게 하는 방법이 있나요? 아니면 더 많은 코드가 필요합니까?

여러 가지 방법이 있습니다.버전 1.8 이전 버전에서는 다음과 같은 간단한 방법이 있습니다.

@JsonDeserialize(as=Cat.class)
public abstract class AbstractAnimal { ... }

속성에 근거해 결정하는 것에 관해서, 그것은 사용하는 것이 최선이다.@JsonTypeInfo자동 삽입(쓰기 시) 및 유형 정보 사용을 수행합니다.

유형 정보(클래스 이름, 논리 유형 이름) 및 포함 메커니즘(as-included-property, as-wrapper-array, as-wrapper-object)에는 여러 종류가 있습니다.이 페이지: https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization 에서는 몇 가지 개념에 대해 설명합니다.

매우 명확한 예를 포함한 완전한 답변은 https://stackoverflow.com/a/30386694/584947에서 찾을 수 있습니다.

잭슨은 이것을 다형성 탈직렬화라고 부른다.

그것은 확실히 내 문제에 도움이 되었다.데이터베이스에 저장하고 있던 추상 클래스를 클래스의 구체적인 인스턴스와 결합 해제해야 했습니다(이해할 수 있습니다).

부모 추상 클래스에 적절한 주석을 다는 방법과 Marshaling을 해제할 때 런타임에 사용 가능한 하위 클래스 후보 중에서 선택하는 방법을 잭슨에게 가르쳐 줍니다.

추가 필드로 JSON을 오염시키지 않고 주석으로 클래스를 오염시키지 않을 경우 원하는 기본 서브클래스를 사용하는 매우 간단한 모듈 및 역직렬라이저를 작성할 수 있습니다.일부 보일러 플레이트 코드로 인해 여러 줄이지만, 여전히 비교적 단순합니다.

class AnimalDeserializer extends StdDeserializer<Animal> {
    public AnimalDeserializer() {
        super(Animal.class);
    }

    public Animal deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException {
        return jsonParser.readValueAs(Cat.class);
    }
}

class AnimalModule extends SimpleModule {
    {
        addDeserializer(Animal.class, new AnimalDeserializer());
    }
}

그런 다음 이 모듈을 ObjectMapper에 등록하면 끝입니다(Zoo는 Animal 필드가 있는 컨테이너 클래스입니다).

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new AnimalModule());
return objectMapper.readValue(json, Zoo.class);

는 ''으로할 수 .@JsonDeserialize추상 수업에서요자세한 내용은 잭슨 예외 문제 및 해결 방법 참조

언급URL : https://stackoverflow.com/questions/5489532/jackson-json-library-how-to-instantiate-a-class-that-contains-abstract-fields

반응형