0

MyKeyLinkedHashMap<MyKey, MyValue>と MyValue は POJO です。

MyKey は getter と setter を持つ Bean であり、hashcode() メソッドをオーバーライドしています。Mapがオブジェクトのhashcode()を使用してキーを形成することをどこかで読んだので、fromJsonと書くと...どのように正確にそれを読んでいますか?

MyKey では、次の関数を定義しました。

@JsonCreator
    public static MyKey fromJSON(String val) throws JsonParseException, JsonMappingException, IOException {
        ObjectMapper mapper = new ObjectMapper();
        MyKey a = mapper.readValue(val,MyKey .class);
        return a;
    }

シリアル化された Json 文字列は、{"MyKey@3":{MyValue..json 文字列}} になります。

次の例外トレースが表示されます。

at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.weirdKeyException(StdDeserializationContext.java:234)
    at org.codehaus.jackson.map.deser.StdKeyDeserializer.deserializeKey(StdKeyDeserializer.java:34)
    at org.codehaus.jackson.map.deser.MapDeserializer._readAndBind(MapDeserializer.java:223)
    at org.codehaus.jackson.map.deser.MapDeserializer.deserialize(MapDeserializer.java:165)
    at org.codehaus.jackson.map.deser.MapDeserializer.deserialize(MapDeserializer.java:25)
    at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
    at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:356)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:368)
    at org.codehaus.jackson.map.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:77)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeWithType(BeanDeserializer.java:423)
    at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:250)
    at org.codehaus.jackson.map.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:595)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:472)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:368)
    at org.codehaus.jackson.map.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:77)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeWithType(BeanDeserializer.java:423)
    at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:250)
    at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:356)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:368)
    at org.codehaus.jackson.map.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:77)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeWithType(BeanDeserializer.java:423)
    at org.codehaus.jackson.map.deser.StdDeserializerProvider$WrappedDeserializer.deserialize(StdDeserializerProvider.java:460)
    at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2395)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1595)

これを修正するにはどうすればよいですか? 可能であれば、json シリアライザーまたはデシリアライザーを登録しないことをお勧めします。

4

1 に答える 1

2

おそらく、例外メッセージはあまり明確ではありませんが、実際に発生するのは、キャッチされる StackOverFlow を取得し、Jackson が代わりに奇妙な KeyException をスローすることです。

問題は JsonCreator です。メソッドで ObjectMapper を使用することはできません。これは、JsonCreator を何度も何度も呼び出すだけだからです。代わりにすべきことは、次のようなものです。

@JsonCreator
public static MyKey fromJSON(String val) throws JsonParseException, JsonMappingException, IOException {
    return new MyKey(val);
}

更新: 明確に見えなかったので、制御フローをもう少し説明しようと思います。

この場合、Jackson のデータバインディング機能 (ObjectMapper を使用) が再帰的に呼び出されます。fromJSON は、JsonCreator で注釈が付けられているため、データバインディング中に呼び出されます。Jackson で MyKey のインスタンスを作成しようとするたびに、そのメソッドが呼び出されます。だから、試してみると

MyKey a = mapper.readValue(val,MyKey .class);

Jackson は fromJSON を呼び出します。それが MyKey の作成方法を知っているからです。

経験則として、Jackson のアノテーションを持つメソッド内で Jackson 機能を使用することは避けています。このような暗黙の再帰があるため、特に注意する必要があります。

于 2012-08-24T15:38:07.943 に答える