잭슨의 object Mapper를 사용하여 인터페이스 필드를 역직렬화하려면 어떻게 해야 합니까?
ObjectMapper
의readValue(InputStream in, Class<T> valueType)
함수에는 클래스가 필요합니다.단, 내부적으로 전달하고 있는 클래스가 데이터 멤버로서 인터페이스를 가지고 있는 경우는, 어떻게 하면 좋을까요.
이 예외의 이면에 있는 이유는 이해할 수 있습니다만, Jackson이 합격 클래스의 내부 인터페이스의 구체적인 클래스를 취득하고 있지 않기 때문에, 제 질문은 어떻게 그것을 해결할 것인가 하는 것입니다.그럼 어떻게 역직렬화하죠?역직렬화하려는 클래스는 다음과 같습니다.
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)
Jackson은 분명히 이 빌딩을 건설할 수 없습니다.MetricValueDescriptor
오브젝트는 인터페이스이기 때문에잭슨에게 오브젝트를 구성하는 방법을 알려주려면 json과 Object Mapper에 추가 정보가 필요합니다.여기 한 가지 방법이 있습니다.MVDImpl
실장하는 구체적인 클래스입니다.MetricValueDescriptor
:
Jackson 자체에 있는 필드를 통해 필요한 유형 정보를 알려줄 수 있습니다."type"
이를 위해서는 인터페이스에서 및 주석을 사용해야 합니다.예를들면,
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@Type(value = MVDImpl.class, name = "mvdimpl") })
interface MetricValueDescriptor
{
...
}
를 추가해야 합니다."type":"mvdimpl"
json에도 입력해 주세요.
더 많은 정보를 얻기 위해 공식 문서를 참조하려고 했는데, 이 주제를 다루는 훌륭한 블로그를 발견했습니다. - 잭슨과 JSON의 역직렬화(Deserialize JSON with Jackson.이 토픽은 꽤 포괄적이고 예를 들어 설명하고 있습니다.따라서 커스터마이즈가 더 필요한 경우 반드시 읽어보시기 바랍니다.
두 가지 방법 중 하나를 사용할 수 있지만 둘 다 인터페이스를 구현하는 구체적인 클래스를 수동으로 만들어야 합니다.
- @Hari Menon의 답변과 사용
@JsonSubTypes
이것은 타입 필드나 다른 것을 도입해, 사용하는 실장을 트리거 할 수 있는 경우에 유효합니다. - 사용하다
@JsonDeserialize
기본적으로 사용되는 콘크리트 클래스를 잭슨에게 알려줍니다.
@JsonDeserialize(as = MVDImpl.class)
interface MetricValueDescriptor
{
...
}
자세한 설명을 드리겠습니다.https://zenidas.wordpress.com/recipes/jackson-deserialization-of-interfaces/
그리고 문서: https://fasterxml.github.io/jackson-databind/javadoc/2.8/com/fasterxml/jackson/databind/annotation/JsonDeserialize.html
코드를 변경할 필요가 없습니다.매퍼에서 프로그래밍 방식으로 설정할 수 있습니다.
static setup() {
final var simpleModule = new SimpleModule()
.addAbstractTypeMapping(<Interface>.class, <Implementation>.class);
objMapper = new ObjectMapper()
.registerModule(new Jdk8Module()) // You probably want this as well
.registerModule(simpleModule);
}
언급URL : https://stackoverflow.com/questions/19379863/how-to-deserialize-interface-fields-using-jacksons-objectmapper
'programing' 카테고리의 다른 글
Angular JSangular-ui 모달 호출 시 $timeout 지우기 (0) | 2023.03.26 |
---|---|
Spring Boot application.properties를 Tomcat/lib 폴더에 외부화하는 방법 (0) | 2023.03.26 |
JSON.stringify(Javascript)와 json.dumps(Python)가 리스트에 기재되어 있지 않습니까? (0) | 2023.03.26 |
JSON 개체에서 not-null 필드를 적용합니다. (0) | 2023.03.26 |
react js의 onClick 이벤트에서 객체 데이터 및 대상 요소 가져오기 (0) | 2023.03.26 |