如何使用Jackson和java.time解析不同的ISO日期/时间格式? [英] How to parse different ISO date/time formats with Jackson and java.time?

查看:311
本文介绍了如何使用Jackson和java.time解析不同的ISO日期/时间格式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆