web-dev-qa-db-ja.com

タイプ[シンプルタイプ、クラスcom.comcast.ivr.core.domain.AutoHandlingSlotKey]の(マップ)キーデシリアライザーが見つかりません

マップを持つドメインオブジェクトがあります。

private Map<AutoHandlingSlotKey, LinkedHashSet<AutoFunction>> autoHandling;

オブジェクトをシリアル化すると、次のようになります。

"autoHandling" : [ "Java.util.HashMap", {
} ],

このマップのキーはカスタムオブジェクトです。

public class AutoHandlingSlotKey implements Serializable {
    private FunctionalArea slot; // ENUM
    private String returnView;   // ENUM

そのため、オブジェクトをデシリアライズするときにこの問題を修正する方法がわかりません。

org.codehaus.jackson.map.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class com.comcast.ivr.core.domain.AutoHandlingSlotKey]

[〜#〜] not [〜#〜]修正するドメインオブジェクトにアクセスできる場合、誰かがこの問題を修正する方法を理解するのを手伝ってくれますか?

39
Mick Knutson

デフォルトでは、JacksonはJava JSONオブジェクト(キー/値のペア)としてマップをシリアライズしようとするため、マップキーオブジェクトは何らかの形で文字列としてシリアライズする必要があります。デフォルト設定では、JDKタイプ(String、number、enum)の小さなセットのみがサポートされているため、マッパーはStringを取得してAutoHandlingSlotKeyを作成する方法がわかりません(実際、シリアライザーが失敗しなかったことに驚いています)同じ理由で)

これを解決する2つの明白な方法は次のとおりです。

  • 「キーデシリアライザー」を実装して登録する
  • Mapsのカスタムデシリアライザーを実装して登録します。

あなたの場合、おそらく前者を行う方が簡単です。また、キーが適切な形式のシリアライザーになるように、カスタムキーシリアライザーを実装することもできます。

シリアライザーとデシリアライザーを登録する最も簡単な方法は モジュールインターフェイス で、これはJackson 1.7で追加されました(そして1.8でキーシリアライザー/デシリアライザーをサポートするために拡張されました)。

22
StaxMan

これはかなり前に尋ねられたもので、エラーを検索したときの最初のグーグルの結果ですが、受け入れられた答えにはコードがなく、ジャクソン初心者(私)にとって混乱するかもしれません。最終的に この答え が助けになった。

そのため、受け入れられた回答に記載されているように、「キーデシリアライザー」を実装して登録することが道です。このようにすることができます。

SimpleModule simpleModule = new SimpleModule();
simpleModule.addKeyDeserializer(YourClass.class, new YourClassKeyDeserializer());
objectMapper.registerModule(simpleModule);

そして、クラスのために、あなたがしなければならないのは:

class YourClassKeyDeserializer extends KeyDeserializer
{
    @Override
    public Object deserializeKey(final String key, final DeserializationContext ctxt ) throws IOException, JsonProcessingException
    {
        return null; // replace null with your logic
    }
}

それでおしまい!クラスの注釈はなく、マップのカスタムデシリアライザーなどはありません。

25
estebanrv