2

これは、型マップを扱う私の最初のタイトルであり、値を持つ FooType としてカスタム プロパティ キーを持つ実際の型オブジェクトにノードをマップしようとするたびにSet<Integer>。これが私のオブジェクトの外観です

public class Foo {
    private String some;
    Map<FooTypes,Set<Integer>> foos;

    public Map<FooTypes, Set<Integer>> getFoos() {
        return foos;
    }
    public void setFoos(Map<FooTypes, Set<Integer>> map) {
        this.foos = map;
    }
    public String getSome() {
        return some;
    }
    public void setSome(String some) {
        this.some = some;
    }
}

public class FooTypes {
    private String name;
    private String id;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
}

今、私はマッパーを使って値を読み取ろうとするたびに:-

List <Foo> response = mapper.readValue("/home/foo/foo.json",List.class);

次のようなエラーが表示されます:-

Can not find a (Map) Key deserializer for type [simple type, class cruft.FooTypes]

誰かがこの問題を解決する方法を教えてもらえますか? ありがとうございました。

Json 出力:-

{"foos":{"FooTypes [id=1, name=Test Foo]":[1,2,3]},"some":hello},{"foos":{"FooTypes [id=2, name=Another foo]":[5,6,7]}}
4

2 に答える 2

8

逆シリアル化する Json 構造がないため、あなたを助けるのは少し難しいですが、ここでの問題は、Jackson がマップ キーとして使用されているときにクラスを逆シリアル化する方法がわからないことです。ジャクソンのすべての情報は単純な文字列であり、クラスは文字列のみでそれを作成する方法を提供しません。

これを達成するには3つの方法があります:

  1. 単一の文字列引数コンストラクターを FooType クラスに追加します
  2. 単一の文字列引数ファクトリ メソッド (静的) を追加し、@JsonCreator で注釈を付けます
  3. カスタムを使用し、フィールドにKeyDeserializer注釈を付けますfoos@JsonDeserialize(keyUsing=YourDeserializer.class)

IMHO静的ファクトリメソッドはよりクリーンな方法です。

于 2012-08-30T17:25:23.430 に答える
2

マップ キー ( )として非プリミティブ型があるため、 Jackson wikiFooTypesで説明されているように独自のカスタム デシリアライザーを記述する必要があります。"FooTypes [id=1, name=Test Foo]"FooTypes.toString()FooTypes

私の意見では、文字列以外のキーを使用してマップをシリアル化することは、実際には良い方法ではありません。JSON 表記では、マップ キーの文字列以外はサポートされていません (ここで指定されているとおり)。より良いアプローチは、シリアル化の前と逆シリアル化の後にデータ構造を再編成することだと思います。

于 2012-08-30T11:51:27.210 に答える