Jackson 1.8.5 的日期解析问题
最近(在过去几个小时左右)我开始收到此异常堆栈:
org.codehaus.jackson.JsonParseException: Numeric value (1316835995324) out of range of int
at [Source: java.io.StringReader@5b082d45; line: 1, column: 642]
at org.codehaus.jackson.JsonParser._constructError(JsonParser.java:1291)
at org.codehaus.jackson.impl.JsonParserMinimalBase._reportError(JsonParserMinimalBase.java:385)
at org.codehaus.jackson.impl.JsonNumericParserBase.convertNumberToInt(JsonNumericParserBase.java:462)
at org.codehaus.jackson.impl.JsonNumericParserBase.getIntValue(JsonNumericParserBase.java:257)
at org.codehaus.jackson.map.deser.StdDeserializer._parseInteger(StdDeserializer.java:237)
at org.codehaus.jackson.map.deser.StdDeserializer$IntegerDeserializer.deserialize(StdDeserializer.java:838)
at org.codehaus.jackson.map.deser.StdDeserializer$IntegerDeserializer.deserialize(StdDeserializer.java:825)
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:350)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:120)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:97)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:26)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:499)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:499)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:120)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:97)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:26)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:499)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:499)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:120)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:97)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:26)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:499)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.ObjectReader._bindAndClose(ObjectReader.java:477)
at org.codehaus.jackson.map.ObjectReader.readValue(ObjectReader.java:253)
这是在反序列化 java.util.Date
时发生的。有趣的是,在这个日期之前,输入流中还有其他类似的日期,并且它们不会引起任何问题。另外,我没有更改正在序列化和反序列化的对象的字段。
有谁知道为什么 Jackson 试图将这个特定的 Date
值反序列化为 int
(而不是 long
)?
预先感谢您的任何见解。
编辑:我对此进行了一些调试,看起来这是 Jackson 尝试处理的第一个 Date
,尽管它仍然出现在流中的较晚位置。我还看到 Jackson 试图强制将此数字转换为 int
,即使在处理的早期阶段它被正确检测为 long
。
编辑2:我对此进行了更多调试并弄清楚了以下内容:只要我没有采用输入参数的setter,序列化/反序列化就可以正常工作,如下所示:
public void setSomeValue(int param)
{
// stuff
this.date = <result_value>
}
当我引入此setter时,Jackson执行不同的代码路径并且最终在它尝试将 long
(java.util.Date
)放入 int
的块中结束。
编辑 3:将设置器名称更改为与字段名称无关的名称可以解决该问题。我仍然想知道原来的方式是否按预期工作(如果是,其背后的想法是什么)或存在错误。
Recently (in the last couple hours or so) I started getting this exception stack:
org.codehaus.jackson.JsonParseException: Numeric value (1316835995324) out of range of int
at [Source: java.io.StringReader@5b082d45; line: 1, column: 642]
at org.codehaus.jackson.JsonParser._constructError(JsonParser.java:1291)
at org.codehaus.jackson.impl.JsonParserMinimalBase._reportError(JsonParserMinimalBase.java:385)
at org.codehaus.jackson.impl.JsonNumericParserBase.convertNumberToInt(JsonNumericParserBase.java:462)
at org.codehaus.jackson.impl.JsonNumericParserBase.getIntValue(JsonNumericParserBase.java:257)
at org.codehaus.jackson.map.deser.StdDeserializer._parseInteger(StdDeserializer.java:237)
at org.codehaus.jackson.map.deser.StdDeserializer$IntegerDeserializer.deserialize(StdDeserializer.java:838)
at org.codehaus.jackson.map.deser.StdDeserializer$IntegerDeserializer.deserialize(StdDeserializer.java:825)
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:350)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:120)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:97)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:26)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:499)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:499)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:120)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:97)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:26)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:499)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:499)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:120)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:97)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:26)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:499)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.ObjectReader._bindAndClose(ObjectReader.java:477)
at org.codehaus.jackson.map.ObjectReader.readValue(ObjectReader.java:253)
This is happening while deserializing a java.util.Date
. The interesing part is that there are other similar Date
s in the input stream before this one and they do not cause any problems. In addition, I did not change the fields of the object that is being serialized and deserialized.
Does anyone have any idea why Jackson is trying to deserialize this particular Date
value into an int
(and not into a long
)?
Thanks in advance for any insight.
EDIT: I debugged this a little and it looks like this is the first Date
that Jackson is trying to process, even though it still comes later in the stream. I also saw that Jackson is trying to force this number into an int
, even though earlier in the processing it is detected properly as a long
.
EDIT 2: I debugged this more and figured out the following: Serialization/deserialization works fine as long as I do not have a setter that takes an input parameter, like this:
public void setSomeValue(int param)
{
// stuff
this.date = <result_value>
}
The moment I introduce this setter, Jackson executes a different code path and ends up in the block where it tries to put a long
(the java.util.Date
) into an int
.
EDIT 3: Changing the setter name to something unrelated to the field name works around the problem. I would still prefer to know if the original way is working as intended (if so, what is the idea behind it) or a bug.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正确——预期的类型由具有最高优先级的变异器确定。因此,由于您的 setter 声明类型是“int”,因此 Jackson 也将其视为“int”。它实际上必须,因为它会调用该设置器;因此,即使您碰巧有一个不同类型的字段(或返回 Date 的 getter),它也没有多大帮助,因为您无法将 Date 作为“int”传递给 set 方法。
INT_MIN int 类型变量的最小值。 –2147483648
INT_MAX int 类型变量的最大值。 2147483647
Right -- type that is expected is determined by mutator with highest priority. So since your setter claims type is 'int', that's what Jackson treats it as. It actually must, since it will call that setter; so even if you happen to have a field with different type (or getter that returns Date), it won't help a lot since you can not pass Date as an 'int' to set method.
INT_MIN Minimum value for a variable of type int. –2147483648
INT_MAX Maximum value for a variable of type int. 2147483647
是的,检查设置器,将 int 更改为 long:
yep, check the setter, change int to long: