Spring rest接口中的LocalDateTime日期类型转时间戳

本文介绍spring-rest接口中的LocalDateTime日期类型转时间戳的方法。

具体的代码参照

示例项目 https://github.com/qihaiyan/springcamp/tree/master/spring-localdatetime-epoch

一、概述

Java程序中一般将日期类型定义为LocalDateTime,数据库中保存的时间是0时区的时间(UTC时间)。对于接口来说,为了支持全球化多时区,接口中的日期类型通常会返回UTC时间戳,简称Epoch,数据类型为long,前端程序会根据本地时区,将时间戳转换为日期格式的字符串,如YYYY-mm-dd HH:mm:ss。

如果在每个时间型字段在接口返回时都进行转换处理,会比较繁琐。应该在一个统一的地方处理这种转换,业务逻辑处理过程中不感知这种转换。

二、通过Jackson2ObjectMapperBuilderCustomizer进行全局类型转换

spring提供了Jackson2ObjectMapperBuilderCustomizer可以用于自定义json与对象之间相互转换的处理。

通过自定义Jackson2ObjectMapperBuilderCustomizer,我们可以在json与对象的相互转换转换阶段完成LocalDateTime和Epoch之间的转换,包括接口的入参和出参。

  1. @Configuration
  2. public class LocalDateTimeToEpochSerdeConfig {
  3.      @Bean
  4.      public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
  5.          return builder -> builder.serializerByType(LocalDateTime.class, new LocalDateTimeToEpochSerializer())
  6.                  .deserializerByType(LocalDateTime.class, new LocalDateTimeFromEpochDeserializer());
  7.      }
  8.      /**
  9.          * 序列化
  10.          */
  11.      public static class LocalDateTimeToEpochSerializer extends JsonSerializer<LocalDateTime> {
  12.          @Override
  13.          public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
  14.                  throws IOException {
  15.              if (value != null) {
  16.                  long timestamp = value.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
  17.                  gen.writeNumber(timestamp);
  18.              }
  19.          }
  20.      }
  21.      /**
  22.          * 反序列化
  23.          */
  24.      public static class LocalDateTimeFromEpochDeserializer extends JsonDeserializer<LocalDateTime> {
  25.          @Override
  26.          public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
  27.              NumberDeserializers.LongDeserializer longDeserializer = new NumberDeserializers.LongDeserializer(Long.TYPE, 0L);
  28.              Long epoch = longDeserializer.deserialize(p, ctxt);
  29.              return LocalDateTime.ofInstant(Instant.ofEpochSecond(epoch), ZoneId.systemDefault());
  30. }
  31.      }
  32. }

以上代码中分别包含了json的序列化和反序列化操作,在序列化操作中,把LocalDateTime转换为Epoch。

  1.      /**
  2.          * 序列化
  3.          */
  4.      public static class LocalDateTimeToEpochSerializer extends JsonSerializer<LocalDateTime> {
  5.          @Override
  6.          public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
  7.                  throws IOException {
  8.              if (value != null) {
  9.                  long timestamp = value.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
  10.                  gen.writeNumber(timestamp);
  11.              }
  12.          }
  13.      }

在反序列化操作中,把Epoch转换为LocalDateTime。

  1.      /**
  2.          * 反序列化
  3.          */
  4.      public static class LocalDateTimeFromEpochDeserializer extends JsonDeserializer<LocalDateTime> {
  5.          @Override
  6.          public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
  7.              NumberDeserializers.LongDeserializer longDeserializer = new NumberDeserializers.LongDeserializer(Long.TYPE, 0L);
  8.              Long epoch = longDeserializer.deserialize(p, ctxt);
  9.              return LocalDateTime.ofInstant(Instant.ofEpochSecond(epoch), ZoneId.systemDefault());
  10.          }
  11.      }

通过以上配置,我们可以在实体类中使用LocalDateTime类型。客户端请求接口时,对于返回结果,自动转换为Epoch数据,对于请求参数,自动从Epoch转换为LocalDateTime。

到此这篇关于Spring rest接口中的LocalDateTime日期类型转时间戳的文章就介绍到这了,更多相关Spring LocalDateTime内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

标签

发表评论