我有LinkedHashMap<MyKey, MyValue>
,MyKey和MyValue是POJO。
MyKey是一个拥有getter和setter的bean,它还覆盖了hashcode()方法。我在某地读过Map将使用对象的hashcode()来形成键,所以如果我从json写出来......它究竟是如何读取它的?
在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;
}
Serialized Json String的格式为{“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序列化器或反序列化器。
答案 0 :(得分:2)
好吧,也许Exception消息不是很清楚,但实际发生的是你得到一个被捕获的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);
杰克逊将从JSON打电话,因为它知道如何创建MyKey。
根据经验,我避免在杰克逊注释的方法中使用杰克逊功能,这只是在寻找麻烦。当你这样做时,你需要格外小心,因为像这样的隐式递归。