3

次のサンプルクラスがあります。

class Zoo {
    public Collection<? extends Animal> animals;
}

シリアル化するときは、次のようにして、できるだけ多くの型情報をシリアル化しようとしています。

  mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

そして、次の JSON を取得します。

[
    "com.bp.samples.json.generics.Zoo",
    {
        "animals": [
            "java.util.ArrayList",
            [
                [
                    "com.bp.samples.json.generics.Bird",
                    {
                        "name": "bird-1",
                        "wingSpan": "6 feets",
                        "preferredFood": "food-1"
                    }
                ],
                [
                    "com.bp.samples.json.generics.Cat",
                    {
                        "name": "cat-1",
                        "favoriteToy": "toy-1"
                    }
                ],
                [
                    "com.bp.samples.json.generics.Dog",
                    {
                        "name": "dog-1",
                        "breed": "bread-1",
                        "leashColor": "black"
                    }
                ]
            ]
        ]
    }
]

逆シリアル化に関しては、次のことを試みます。

mapper.readValue(new File("./DataFiles/Zoo-2.json"), Zoo.class);

次の例外が発生します。

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: 
Can not deserialize instance of com.bp.samples.json.generics.Zoo out of START_ARRAY toke

やろうとしている:

mapper.readValue(new File("./DataFiles/Zoo-2.json"), 
   new TypeReference<Collection<? extends Animal>>() {});

結果:

Can not construct instance of com.bp.samples.json.generics.Animal, 
problem: abstract types either need to be mapped to concrete types, have custom 
deserializer, or be instantiated with additional type information
at [Source: ./DataFiles/Zoo-2.json; line: 2, column: 5]

もちろん、カスタム デシリアライザーを作成することで問題は解決しますが、カスタム デシリアライザーを使用せずにデシリアライズする方法はありますか?

ありがとう、ベザド

4

2 に答える 2

2

あなたの最初の試みは私が見る限りうまくいくはずです。私が考えることができる唯一の説明はObjectMapper、逆シリアル化のために異なる構成を使用しようとしているということです。どちらも同じ方法でデフォルトの入力を有効にする必要があります(これが型情報を含めるかどうかを制御するためです)。

同じマッパーインスタンスを使用している(または同じように構成されている)場合は、バグレポートを提出して、問題を診断して修正することをお勧めします。

于 2013-01-04T22:56:30.443 に答える
1

デシリアライズに使用するObjectMapperインスタンスのタイプ情報を有効にしたことを確認してください。動物のコレクションではなく動物園に逆シリアル化したいので、最初のコードスニペットは正しいです。

Gensonlibを試してみることもできます。私はあなたの例をそれでチェックしました、そしてすべてがうまくいくようです。Gensonでポリモーフィック型のサポートを有効にするには、gensonインスタンスを構成する必要があります。

Genson genson = new Genson.Builder().setWithClassMetadata(true).create();
于 2013-01-04T20:41:35.143 に答える