Jackson の objectMapper を使用してインターフェース フィールドをデシリアライズする方法は? 質問する

Jackson の objectMapper を使用してインターフェース フィールドをデシリアライズする方法は? 質問する

ObjectMapperreadValue(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)

ベストアンサー1

ジャクソンはMetricValueDescriptorインターフェースなので、当然オブジェクトを構築できません。ジャクソンにオブジェクトの構築方法を伝えるには、json と ObjectMapper に追加情報が必要です。以下は、 を実装するMVDImpl具体的なクラスであると仮定して、それを実行する 1 つの方法ですMetricValueDescriptor

たとえば、JSON自体のフィールドを通じて、必要な型情報をJacksonに伝えることができます"type"。これを行うには、JsonTypeInfoそしてJsonSubTypesインターフェースに注釈を追加します。たとえば、

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

"type":"mvdimpl"json にもフィールドを追加する必要があります。

私はあなたに公式ドキュメントさらに詳しい情報を探していたのですが、このトピックを扱った素晴らしいブログを見つけました。Jackson で JSON をデシリアライズするこのトピックについては、例を挙げながらかなり包括的に解説されています。したがって、さらにカスタマイズが必要な場合は、必ず読んでください。

おすすめ記事