如何使用Jackson和java.time解析不同的ISO日期/时间格式? [英] How to parse different ISO date/time formats with Jackson and java.time?
问题描述
我们的Rest API从多个外部参与者获取JSON输入.它们都使用"ISO-ish"格式,但是时区偏移量的格式略有不同.这些是我们看到的一些最常见的格式:
Our Rest API takes JSON input from several external parties. They all use "ISO-ish" formats, but the formatting of the time zone offset is slightly different. These are some of the most common formats we see:
2018-01-01T15:56:31.410Z
2018-01-01T15:56:31.41Z
2018-01-01T15:56:31Z
2018-01-01T15:56:31+00:00
2018-01-01T15:56:31+0000
2018-01-01T15:56:31+00
我们的堆栈是带有Jackson ObjectMapper的Spring Boot 2.0.在我们的数据类中,我们经常使用java.time.OffsetDateTime
类型.
Our stack is Spring Boot 2.0 with Jackson ObjectMapper. In our data classes we use the type java.time.OffsetDateTime
a lot.
几个开发人员试图实现一种解析上述所有格式的解决方案,但都没有成功.尤其是带有冒号(00:00
)的第四个变体似乎无法解析.
Several developers have tried to achieve a solution that parses all of the above formats, none have been successful. Particularly the fourth variant with a colon (00:00
) seems to be unparseable.
如果解决方案能够有效运行而不必在模型的每个日期/时间字段上添加注释,那就太好了.
It would be great if the solution works without having to place an annotation on each and every date/time field of our models.
亲爱的社区,您有解决方案吗?
Dear community, do you have a solution?
推荐答案
非常感谢您的所有输入!
Thank you very much for all your input!
我选择了jeedas建议的解串器和Ole V.V建议的格式化程序(因为它更短).
I chose the deserializer suggested by jeedas combined with the formatter suggested by Ole V.V (because it's shorter).
class DefensiveIsoOffsetDateTimeDeserializer : JsonDeserializer<OffsetDateTime>() {
private val formatter = DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("[XXX][XX][X]")
.toFormatter()
override fun deserialize(p: JsonParser, ctxt: DeserializationContext)
= OffsetDateTime.parse(p.text, formatter)
override fun handledType() = OffsetDateTime::class.java
}
我还添加了一个自定义序列化程序,以确保在生成json时使用正确的格式:
I also added a custom serializer to make sure we use the correct format when producing json:
class OffsetDateTimeSerializer: JsonSerializer<OffsetDateTime>() {
override fun serialize(
value: OffsetDateTime,
gen: JsonGenerator,
serializers: SerializerProvider
) = gen.writeString(value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME))
override fun handledType() = OffsetDateTime::class.java
}
将所有部分放在一起,我在spring类路径中添加了一个@Configuraton
类,以使其在数据类上没有任何注释地工作:
Putting all the parts together, I added a @Configuraton
class to my spring classpath to make it work without any annotations on the data classes:
@Configuration
open class JacksonConfig {
@Bean
open fun jacksonCustomizer() = Jackson2ObjectMapperBuilderCustomizer {
it.deserializers(DefensiveIsoOffsetDateTimeDeserializer())
it.serializers(OffsetDateTimeSerializer())
}
}
这篇关于如何使用Jackson和java.time解析不同的ISO日期/时间格式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!