45

JSON 文字列を Java オブジェクトに変換したいのですが、このオブジェクトのクラスには、Jackson がインスタンス化できない抽象フィールドが含まれており、オブジェクトを生成しません。次のような抽象クラスのデフォルトの実装について伝える最も簡単な方法は何ですか?

setDefault(AbstractAnimal.class, Cat.class);

または、JSON 属性名に基づいて実装クラスを決定します。JSON オブジェクトの場合:

{
    ...
    cat: {...}
    ...
}

私はただ嘆くでしょう:

setImpl("cat", Cat.class);


Jackson で JSON 内にクラス情報を埋め込むことが可能であることはわかっていますが、使用する JSON 形式を複雑にしたくありません。デフォルトの実装クラスを設定するだけで、または属性名(「cat」)で使用するクラスを決定したい-XStreamライブラリのように、次のように記述します:

xStream.alias("cat", Cat.class);

特に1行でそうする方法はありますか、それとももう少しコードが必要ですか?

4

4 に答える 4

60

複数の方法があります。バージョン 1.8 より前では、おそらく最も簡単な方法は次のとおりです。

@JsonDeserialize(as=Cat.class)
public abstract class AbstractAnimal { ... }

属性に基づいて決定する@JsonTypeInfo場合は、自動埋め込み (書き込み時) と型情報の使用を行う を使用するのが最適です。

複数の種類の型情報 (クラス名、論理型名) と包含メカニズム (as-included-property、as-wrapper-array、as-wrapper-object) があります。このページ: https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserializationでは、いくつかの概念について説明しています。

于 2011-03-31T17:13:59.380 に答える
4

JSON を余分なフィールドで汚染したり、クラスを注釈で汚染したりしたくない場合は、必要なデフォルトのサブクラスを使用する非常に単純なモジュールとデシリアライザーを作成できます。いくつかの定型コードのために複数の行になっていますが、それでも比較的単純です。

class AnimalDeserializer extends StdDeserializer<Animal> {
    public AnimalDeserializer() {
        super(Animal.class);
    }

    public Animal deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException {
        return jsonParser.readValueAs(Cat.class);
    }
}

class AnimalModule extends SimpleModule {
    {
        addDeserializer(Animal.class, new AnimalDeserializer());
    }
}

次に、このモジュールを ObjectMapper に登録します。これで完了です (Zoo は Animal フィールドを持つコンテナー クラスです)。

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new AnimalModule());
return objectMapper.readValue(json, Zoo.class);
于 2019-02-01T14:16:31.457 に答える