25

次のようなマップがあります。

public class VerbResult {
    @JsonProperty("similarVerbs")
    private Map<Verb, List<Verb>> similarVerbs;
}

私の動詞クラスは次のようになります。

public class Verb extends Word {
    @JsonCreator
    public Verb(@JsonProperty("start") int start, @JsonProperty("length") int length,
            @JsonProperty("type") String type, @JsonProperty("value") VerbInfo value) {
        super(length, length, type, value);
    }
    //...
}

VerbResult クラスのインスタンスをシリアライズおよびデシリアライズしたいのですが、実行すると次のエラーが発生します。Can not find a (Map) Key deserializer for type [simple type, class my.package.Verb]

マップキーをデシリアライズする方法をジャクソンに伝える必要があることをオンラインで読みましたが、これを行う方法を説明する情報は見つかりませんでした。動詞クラスは、マップの外部でもシリアライズおよびデシリアライズする必要があるため、どのソリューションでもこの機能を維持する必要があります。

ご協力ありがとうございました。

4

4 に答える 4

42

1 日検索した後、この質問に基づいて、より簡単な方法を見つけました。@JsonDeserialize(keyUsing = YourCustomDeserializer.class)解決策は、注釈をマップに追加することでした。KeyDeserializer次に、メソッドを拡張およびオーバーライドして、カスタム デシリアライザーを実装しますdeserializeKey。このメソッドは文字列キーで呼び出され、文字列を使用して実際のオブジェクトを構築したり、データベースから既存のオブジェクトを取得したりすることもできます。

したがって、最初にマップ宣言で:

@JsonDeserialize(keyUsing = MyCustomDeserializer.class)
private Map<Verb, List<Verb>> similarVerbs;

次に、文字列キーで呼び出されるデシリアライザーを作成します。

public class MyCustomDeserializer extends KeyDeserializer {
    @Override
    public MyMapKey deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        //Use the string key here to return a real map key object
        return mapKey;
    }
}

Jersey および Jackson 2.x で動作

于 2016-07-07T11:47:42.720 に答える
13

上で述べたように、重要なデシリアライザーが必要だというのが秘訣です(これには私も気付きました)。私の場合、クラスで文字列以外のマップキーが構成されていましたが、解析していた JSON には含まれていなかったため、非常に単純な解決策が機能しました (単にキーデシリアライザーで null を返すだけでした)。

public class ExampleClassKeyDeserializer extends KeyDeserializer
{
    @Override
    public Object deserializeKey( final String key,
                                  final DeserializationContext ctxt )
       throws IOException, JsonProcessingException
    {
        return null;
    }
}

public class ExampleJacksonModule extends SimpleModule
{
    public ExampleJacksonModule()
    {
        addKeyDeserializer(
            ExampleClass.class,
            new ExampleClassKeyDeserializer() );
    }
}

final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule( new ExampleJacksonModule() );
于 2014-11-17T21:17:49.113 に答える
6

デシリアライザーを使用してモジュールを実装することを提案する、ここで与えられた答えに基づいて構築します。JodaTimeモジュールは、シリアライザーとデシリアライザーを含むモジュールの完全な例を理解しやすいものです。

モジュール機能はJacksonバージョン1.7で導入されたため、アップグレードが必要になる場合があることに注意してください。

だからステップバイステップ:

  1. Jodaの例に基づいて、クラスの(デ)シリアライザーを含むモジュールを作成します
  2. そのモジュールをに登録するmapper.registerModule(module);

そして、あなたはすべて設定されます

于 2012-06-28T14:41:57.620 に答える
0

Web を精査した結果、POJO スタイルのキーを処理する方法について適切な解決策があると思います (ただし、いつものように、完全なオブジェクトをマップ キーとして使用しないことをお勧めします)。

シリアライザー (Spring Boot 内で Jackson モジュールとして登録):

@Bean
fun addKeySerializer(): Module =
    SimpleModule().addKeySerializer(YourClass::class.java, YourClassSerializer())

class YourClassSerializer() : JsonSerializer<YourClass>() {
    override fun serialize(value: DataElement, gen: JsonGenerator, serializers: SerializerProvider) {
        gen.writeFieldName(jacksonObjectMapper().writeValueAsString(value))
    }
}

(標準の Java 環境では、ここで独自のインスタンスをインスタンス化する必要があることに注意してくださいobjectMapper)

デシリアライザー:

@Bean
fun addKeyDeserializer(): Module =
    SimpleModule().addKeyDeserializer(YourClass::class.java, YourClassDeserializer())

class YourClassDeserializer() : KeyDeserializer() {
    override fun deserializeKey(key: String, ctxt: DeserializationContext): YourClass? {
        return ctxt.parser.readValueAs(YourClass::class.java)
    }
}
于 2021-10-08T18:16:49.547 に答える