Ada*_*fin 5 java datetime parsing jackson deserialization
我在 Spring 启动应用程序中使用了一个 Java 类来反序列化来自具有如下字段的请求的 json 对象:
@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss[.SSS]XXX", timezone = "UTC")
Instant timestamp;
Run Code Online (Sandbox Code Playgroud)
它使用 Jackson V2.6.6 @JsonFormat 注释反序列化来自网络的 JSON 中的“时间戳”字段。
我看到的是,当价值是这样的:
“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]
Run Code Online (Sandbox Code Playgroud)
我能做些什么来修复这个模式,以便它可以灵活地接受小数第二位小数位数?我知道在 Java 日期格式中有一个宽松的概念:https : //docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
但我不确定如何将对象映射器设置为宽松模式。
只是猜测\xe2\x80\xa6
\n\n我怀疑您可能在 Java 8 的早期版本中遇到了一些 java.time 错误。有几个与解析相关的错误,一些在 Java 8 的后续更新中修复,一些在 Java 9 中修复。
\n\n我猜测1.8.0_65
您的错误文本中的字符串是指 Java 8 Update 65。目前Oracle 实现位于 Update 121。
我不认识杰克逊。DateTimeFormatter
我想知道他们到底援引了什么。我在您的错误引用中没有看到该信息。
您可以省略定义模式并查看 Jackson 的默认行为吗?
\n\nInstant.parse
Instant.parse
当我在配备 16 GB RAM、运行 macOS Sierra 10.12.3 和 NetBeans 8.2 的 MacBook Pro(视网膜屏,15 英寸,2013 年末)上调用 Java 8 Update 121 来解析字符串时,没有发现这样的问题。
System.out.println ( "Java vendor: " + System.getProperty ( "java.vendor" ) );\nSystem.out.println ( "Java version: " + System.getProperty ( "java.version" ) );\n\nList<String> strings = new ArrayList<> ();\nstrings.add ( "2017-01-09T21:49:26.7Z" );\nstrings.add ( "2017-01-09T21:49:26.70Z" );\nstrings.add ( "2017-01-09T21:49:26.700Z" );\nstrings.add ( "2017-01-09T21:49:26.7000Z" );\nstrings.add ( "2017-01-09T21:49:26.70000Z" );\n\nfor ( String string : strings ) {\n try {\n Instant instant = Instant.parse ( string );\n System.out.println ( "GOOD - string: " + string + " parsed: " + instant );\n } catch ( DateTimeParseException e ) {\n System.out.println ( "ERROR - Failed to parse string: " + string );\n }\n}\nSystem.out.println ( "Done." );\n
Run Code Online (Sandbox Code Playgroud)\n\n运行时。
\n\nSystem.out.println ( "Java vendor: " + System.getProperty ( "java.vendor" ) );\nSystem.out.println ( "Java version: " + System.getProperty ( "java.version" ) );\n\nList<String> strings = new ArrayList<> ();\nstrings.add ( "2017-01-09T21:49:26.7Z" );\nstrings.add ( "2017-01-09T21:49:26.70Z" );\nstrings.add ( "2017-01-09T21:49:26.700Z" );\nstrings.add ( "2017-01-09T21:49:26.7000Z" );\nstrings.add ( "2017-01-09T21:49:26.70000Z" );\n\nfor ( String string : strings ) {\n try {\n Instant instant = Instant.parse ( string );\n System.out.println ( "GOOD - string: " + string + " parsed: " + instant );\n } catch ( DateTimeParseException e ) {\n System.out.println ( "ERROR - Failed to parse string: " + string );\n }\n}\nSystem.out.println ( "Done." );\n
Run Code Online (Sandbox Code Playgroud)\n\n您还可以看到相同的代码在 IdeOne.com 上实时运行,没有任何问题,运行 Oracle 实现的 Java 8 Update 121。
\n\nDateTimeFormatter.ofPattern
我也尝试了你的格式模式。它适用于.70
但.700
不适用于其他人。
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "yyyy-MM-dd\'T\'HH:mm:ss[.SSS]XXX" , Locale.US );\nfor ( String string : strings ) {\n try {\n OffsetDateTime odt = OffsetDateTime.parse ( string , f );\n System.out.println ( "GOOD - string: " + string + " parsed: " + odt );\n } catch ( DateTimeParseException e ) {\n System.out.println ( "ERROR - Failed to parse string: " + string );\n }\n}\nSystem.out.println ( "Done with \'DateTimeFormatter.ofPattern\'." );\n
Run Code Online (Sandbox Code Playgroud)\n\nJava vendor: Oracle Corporation\nJava version: 1.8.0_121\nGOOD - string: 2017-01-09T21:49:26.7Z parsed: 2017-01-09T21:49:26.700Z\nGOOD - string: 2017-01-09T21:49:26.70Z parsed: 2017-01-09T21:49:26.700Z\nGOOD - string: 2017-01-09T21:49:26.700Z parsed: 2017-01-09T21:49:26.700Z\nGOOD - string: 2017-01-09T21:49:26.7000Z parsed: 2017-01-09T21:49:26.700Z\nGOOD - string: 2017-01-09T21:49:26.70000Z parsed: 2017-01-09T21:49:26.700Z\n
Run Code Online (Sandbox Code Playgroud)\n\n仅供参考,字符串的格式如ISO 86012017-01-09T21:49:26.70Z
标准中定义的。在解析或生成表示日期时间值的字符串时,java.time 类默认使用这些标准 ISO 8601 格式。
该特定格式使用 aT
将年-月-日部分与时-分-秒部分分开。是UTCZ
的缩写Zulu
,表示UTC。
您可以通过搜索 StackOverflow查看更多信息。
\n