카테고리 없음

Jackson의 objectMapper를 사용하여 인터페이스 필드를 역 직렬화하는 방법은 무엇입니까?

기록만이살길 2021. 2. 27. 03:27
반응형

Jackson의 objectMapper를 사용하여 인터페이스 필드를 역 직렬화하는 방법은 무엇입니까?

1. 질문(문제점):

ObjectMapperreadValue(InputStream in, Class<T> valueType)기능에는 Class가 필요합니다. 그러나 내부적으로 전달하는 클래스가 일부 인터페이스를 데이터 멤버로 사용하는 경우 어떻게 사용합니까?

Jackson이 전달 된 클래스의 내부 인터페이스의 구체적인 클래스를 얻지 못하기 때문에이 예외의 원인을 이해할 수 있지만 내 질문은 어떻게 해결할 수 있습니까? 그런 다음 어떻게 deserialize합니까? 역 직렬화하려는 클래스는 다음과 같습니다.

class BaseMetricImpl<N> implements Metric<N> {
    protected MetricValueDescriptor descriptor;
}

다음 MetricValueDescriptor은 인터페이스이므로 다음과 같은 오류가 발생합니다.-

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of MetricValueDescriptor, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
 at [Source: java.io.ByteArrayInputStream@2ede2c9f; line: 1, column: 2] (through reference chain: SingleValueMetricImpl["descriptor"])
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
    at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:624)
    at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:115)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:308)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2793)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1989)

2. 해결방안:

Jackson MetricValueDescriptor은 인터페이스이기 때문에 분명히 객체를 구성 할 수 없습니다 . jackson에게 객체를 생성하는 방법을 알려주려면 json과 ObjectMapper에 추가 정보가 있어야합니다. 다음 MVDImpl을 구현하는 구체적인 클래스가 있다고 가정하면 한 가지 방법 이 있습니다 MetricValueDescriptor.

json 자체의 필드를 통해 Jackson에게 필요한 유형 정보를 알릴 수 있습니다 "type". 이렇게하려면 인터페이스에서 JsonTypeInfoJsonSubTypes주석 을 사용해야 합니다. 예를 들면

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
@JsonSubTypes({
    @Type(value = MVDImpl.class, name = "mvdimpl") })
interface MetricValueDescriptor
{
   ...
}

"type":"mvdimpl"json에도 필드 를 추가해야합니다 .

자세한 정보 공식 문서 를 참조하려고했지만이 주제를 다루는 훌륭한 블로그 인 Deserialize JSON with Jackson을 찾았습니다 . 이 주제를 매우 포괄적이고 예제로 다룹니다. 따라서 더 많은 사용자 정의가 필요한 경우 반드시 읽어야합니다.

65778720
반응형