Json - 关键异常? [英] Json - weired key exception?

查看:124
本文介绍了Json - 关键异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 LinkedHashMap< MyKey,MyValue> ,MyKey和MyValue是POJO。

I have a LinkedHashMap<MyKey, MyValue>, MyKey and MyValue are the POJOs.

MyKey是一个有getter和setter的bean,它也有重写的hashcode()方法。我在某处读到Map会使用对象的hashcode()来形成键,所以如果我从json写出来......它到底是怎么读的?

MyKey is a bean which has getters and setters, it also has overridden hashcode() method. I read somewhere that Map will use hashcode() of object to form key, so if i write fromJson... how exactly is it reading it?

在MyKey我有定义以下函数:

In MyKey i have defined following function:

@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 string}}。

The Serialized Json String is going as {"MyKey@3":{MyValue.. json string}}.

我得到以下异常跟踪:

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序列化器或反序列化器。

How should i fix this? I would prefer not to register json serializer or deserializer if possible.

推荐答案

好吧,也许Exception消息不是很清楚,但是实际发生的是你得到一个被捕获的StackOverFlow而Jackson会抛出一个奇怪的键异常。

Well, perhaps the Exception message is not very clear, but what actually happens is you get a StackOverFlow that gets catched and Jackson instead throws a weirdKeyException.

问题是你的JsonCreator:你不能在你的方法中使用ObjectMapper,因为这将简单地一次又一次地调用JsonCreator。您应该做的事情如下:

The problem is your JsonCreator: you can't use the ObjectMapper in your method because that will simply call the JsonCreator again and again and again. What you should do instead is something like the following:

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

更新:因为它似乎没有很清楚我会尝试更多地解释控制流程。

Update: Since it didn't appear to be clear I'll try to explain a bit more the control flow.

在这种情况下会发生的事情是Jackson(带ObjectMapper)的数据绑定功能被递归调用。在数据绑定期间调用fromJSON,因为它使用JsonCreator注释;任何时候你尝试用Jackson创建一个MyKey实例,这个方法都会被调用。所以,当你尝试

What happens in this case is that the databinding functionnality of Jackson (with ObjectMapper) gets called recursively. The fromJSON is called during databinding because it is annotated with JsonCreator; any time you try to create an instance of MyKey with Jackson that method will be called. So, when you try

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

杰克逊将从JSON调用,因为它知道如何创建MyKey。

Jackson will call fromJSON, because that's how it knows to create MyKey.

根据经验,我避免在杰克逊注释的方法中使用杰克逊功能,这只是在寻找麻烦。当你这样做时,你需要格外小心,因为像这样的隐式递归。

As a rule of thumb, I avoid using Jackson functionality inside of methods that have annotations for Jackson, that's just asking for trouble. When you do you need to be extra careful because of the implicit recursion like this one.

这篇关于Json - 关键异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆