我在Spring启动应用程序中使用了一个Java类来反序序列化来自请求的json对象,其字段如下:
@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss[.SSS]XXX", timezone = "UTC")
Instant timestamp;
它正在使用Jackson V2.6.6 @JsonFormat注释反序列化通过网络传输的JSON中的“timestamp”字段。
我所看到的是,当价值如下:
“2017-01-09T21:49:26.70Z”
没有问题。
但是,如果该值包含单个小数点后第二位小数,或者超过三位小数,则为:
“2017-01-09T21:49:26.7Z”或“2017-01-09T21:49:26.7000Z”
然后我会收到以下错误:
Caused by: java.time.format.DateTimeParseException: Text '2017-01-09T21:49:26.7Z' could not be parsed at index 19
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) ~[?:1.8.0_65]
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1777) ~[?:1.8.0_65]
at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer.deserialize(InstantDeserializer.java:150) ~[jackson-datatype-jsr310-2.6.6.jar:2.6.6]
at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer.deserialize(InstantDeserializer.java:45) ~[jackson-datatype-jsr310-2.6.6.jar:2.6.6]
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520) ~[jackson-databind-2.6.6.jar:2.6.6]
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:101) ~[jackson-databind-2.6.6.jar:2.6.6]
at com.fasterxml.jackson.module.afterburner.deser.SuperSonicBeanDeserializer.deserialize(SuperSonicBeanDeserializer.java:156) ~[jackson-module-afterburner-2.6.6.jar:2.6.6]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736) ~[jackson-databind-2.6.6.jar:2.6.6]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2764) ~[jackson-databind-2.6.6.jar:2.6.6]
我可以做些什么来修复这个模式,以便它可以灵活地接受它接受的小数点后第二位数?我知道Java日期格式有一个宽松的概念:https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
但我不确定如何将对象映射器设置为宽松模式。
答案 0 :(得分:0)
只是一个猜测......
我怀疑你可能在早期版本的Java 8中遇到了一些java.time错误。有几个解析相关的错误,一些在Java 8的后续更新中得到修复,一些在Java 9中得到修复。
我猜你的错误文本中的1.8.0_65
字符串是指Java 8 Update 65.目前是Oracle implementation is at Update 121。
我不知道Jackson。我想知道他们正在调用的确切DateTimeFormatter
。我在错误报价中没有看到这些信息。
您是否可以省略定义模式并查看杰克逊的默认行为?
Instant.parse
我在MacBook Pro(Retina,15英寸,2013年末)的Java 8 Update 121中调用Instant.parse
解析字符串时看到没有这样的问题,其中16个内存运行macOS Sierra 10.12.3 NetBeans 8.2。
System.out.println ( "Java vendor: " + System.getProperty ( "java.vendor" ) );
System.out.println ( "Java version: " + System.getProperty ( "java.version" ) );
List<String> strings = new ArrayList<> ();
strings.add ( "2017-01-09T21:49:26.7Z" );
strings.add ( "2017-01-09T21:49:26.70Z" );
strings.add ( "2017-01-09T21:49:26.700Z" );
strings.add ( "2017-01-09T21:49:26.7000Z" );
strings.add ( "2017-01-09T21:49:26.70000Z" );
for ( String string : strings ) {
try {
Instant instant = Instant.parse ( string );
System.out.println ( "GOOD - string: " + string + " parsed: " + instant );
} catch ( DateTimeParseException e ) {
System.out.println ( "ERROR - Failed to parse string: " + string );
}
}
System.out.println ( "Done." );
跑步时。
Java vendor: Oracle Corporation
Java version: 1.8.0_121
GOOD - string: 2017-01-09T21:49:26.7Z parsed: 2017-01-09T21:49:26.700Z
GOOD - string: 2017-01-09T21:49:26.70Z parsed: 2017-01-09T21:49:26.700Z
GOOD - string: 2017-01-09T21:49:26.700Z parsed: 2017-01-09T21:49:26.700Z
GOOD - string: 2017-01-09T21:49:26.7000Z parsed: 2017-01-09T21:49:26.700Z
GOOD - string: 2017-01-09T21:49:26.70000Z parsed: 2017-01-09T21:49:26.700Z
您也可以毫无问题地看到同样的code run live at IdeOne.com,运行Oracle实现的Java 8 Update 121.
DateTimeFormatter.ofPattern
我也尝试了你的格式化模式。它适用于.70
和.700
,但不适用于其他人。
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "yyyy-MM-dd'T'HH:mm:ss[.SSS]XXX" , Locale.US );
for ( String string : strings ) {
try {
OffsetDateTime odt = OffsetDateTime.parse ( string , f );
System.out.println ( "GOOD - string: " + string + " parsed: " + odt );
} catch ( DateTimeParseException e ) {
System.out.println ( "ERROR - Failed to parse string: " + string );
}
}
System.out.println ( "Done with 'DateTimeFormatter.ofPattern'." );
ERROR - Failed to parse string: 2017-01-09T21:49:26.7Z
GOOD - string: 2017-01-09T21:49:26.70Z parsed: 2017-01-09T21:49:26.700Z
GOOD - string: 2017-01-09T21:49:26.700Z parsed: 2017-01-09T21:49:26.700Z
ERROR - Failed to parse string: 2017-01-09T21:49:26.7000Z
ERROR - Failed to parse string: 2017-01-09T21:49:26.70000Z
仅供参考,2017-01-09T21:49:26.70Z
等字符串的格式在ISO 8601标准中定义。在解析或生成表示日期时间值的字符串时,java.time类默认使用这些标准的ISO 8601格式。
该特定格式使用T
将年 - 月 - 日期部分与小时 - 分 - 秒部分分开。 Z
是Zulu
的缩写,表示UTC。
您可以通过searching StackOverflow查看更多信息。