web-dev-qa-db-ja.com

Java:インターフェイスプロパティを持つオブジェクトのジャクソンポリモーフィックJSON逆シリアル化?

JacksonのObjectMapperを使用して、プロパティの1つとしてインターフェイスを含むオブジェクトのJSON表現を逆シリアル化しています。コードの簡略版は次のとおりです。

https://Gist.github.com/sscovil/873592

基本的に、私はAssettypeの2つのプロパティを持つクラスpropertiesを持っています。 JSONモデルは次のようになります。

{
    "type": "document",
    "properties": {
        "source": "foo",
        "proxy": "bar"
    }
}

propertiesプロパティはAssetPropertiesと呼ばれるインターフェイスとして定義されており、それを実装するクラスがいくつかあります(例:DocumentAssetPropertiesImageAssetProperties)。イメージファイルは、ドキュメントファイルなどとは異なるプロパティ(高さ、幅)を持つという考え方です。

私は この記事 の例に取り組み、SO以降)のドキュメントと質問を読み、@JsonTypeInfoアノテーションパラメータのさまざまな構成を実験しました。このナットをクラックすることができませんでした。

最近、私が得ている例外はこれです:

Java.lang.AssertionError: Could not deserialize JSON.
...
Caused by: org.codehaus.jackson.map.JsonMappingException: Could not resolve type id 'source' into a subtype of [simple type, class AssetProperties]

前もって感謝します!

解決策:

@MichałZioberに感謝し、この問題を解決することができました。 EnumをタイプIDとして使用することもできましたが、これには少しグーグルがかかりました。動作するコードを含む更新されたGistは次のとおりです。

https://Gist.github.com/sscovil/8788339

19
Shaun Scovil

JsonTypeInfo.As.EXTERNAL_PROPERTYの代わりにJsonTypeInfo.As.PROPERTYを使用する必要があります。このシナリオでは、Assetクラスは次のようになります。

class Asset {

    @JsonTypeInfo(
            use = JsonTypeInfo.Id.NAME,
            include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
            property = "type")
    @JsonSubTypes({
        @JsonSubTypes.Type(value = ImageAssetProperties.class, name = "image"),
        @JsonSubTypes.Type(value = DocumentAssetProperties.class, name = "document") })
    private AssetProperties properties;

    public AssetProperties getProperties() {
        return properties;
    }

    public void setProperties(AssetProperties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "Asset [properties("+properties.getClass().getSimpleName()+")=" + properties + "]";
    }
}

この質問の私の回答も参照してください: Jackson JsonTypeInfo.As.EXTERNAL_PROPERTYが期待どおりに機能しない

18
Michał Ziober