SpringBoot 使用 Jackson 处理 Java8 时间 API


SpringBoot 使用 Jackson 处理 Java8 时间 API

场景

在项目中的实体类里面使用了 Java8 新的时间 API,例如 LocalDate, LocalTime, LocalDateTime 等。然而在将这些时间类型的字段序列化返回到前端时,但格式却感觉有些异常。

嗯,大概就是下面这种样子的

{
  "dayOfMonth": 27,
  "dayOfWeek": "MONDAY",
  "dayOfYear": 239,
  "month": "AUGUST",
  "monthValue": 8,
  "year": 2018,
  "hour": 10,
  "minute": 0,
  "nano": 370000000,
  "second": 52,
  "chronology": {
    "id": "ISO",
    "calendarType": "iso8601"
  }
}

这是什么鬼的格式。。。

解决方案

添加依赖

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

修改 application.yml,配置 spring.jackson.serialization.write_dates_as_timestamps 禁用 _打印日期为时间戳的功能_。

spring:
  jackson:
    serialization:
      write_dates_as_timestamps: false

如此,在返回数据到前端的时候 SpringBoot 就会自动将日期格式化为 yyyy-MM-ddThh:mm:ss

然而,如果我们想要在程序中手动的序列化日期怎么办呢?实际上也很简单,使用代码 .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) 来禁止序列化时间为时间戳并注册 jackson-datatype-jsr310 中的 JavaTimeModule 模块。

下面是吾辈在项目里使用的一个全局 ObjectMapper 对象

/**
  * 提供一个全局可用的序列化 Bean
  */
public static final ObjectMapper OM = new ObjectMapper()
        //Date 对象的格式
        .setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"))
        //禁止序列化值为 null 的属性
        .setSerializationInclusion(JsonInclude.Include.NON_NULL)
        //禁止序列化时间为时间戳
        .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
        .registerModules(
                //注册 Jsr310(Java8 的时间兼容模块)
                new JavaTimeModule(),
                //序列化 Long 为 String
                new SimpleModule()
                        //大数字直接序列化为 String
                        .addSerializer(Long.class, ToStringSerializer.instance)
                        .addSerializer(Long.TYPE, ToStringSerializer.instance)
                        .addSerializer(long.class, ToStringSerializer.instance)
                        .addSerializer(BigInteger.class, ToStringSerializer.instance)
                        //大浮点数直接序列化为 String
                        .addSerializer(BigDecimal.class, new JsonSerializer<BigDecimal>() {
                            @Override
                            public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                                gen.writeString(value.setScale(10, BigDecimal.ROUND_HALF_UP).toPlainString());
                            }
                        })
        )
        //JSON 序列化移除 transient 修饰的 Page 无关紧要的返回属性(Mybatis Plus)
        .configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);

那么,以上就是 SpringBoot 序列化 Java8 时间 API 的问题和解决方案啦 ヾ(@^▽^@)ノ


文章作者: rxliuli
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 rxliuli !
 上一篇
使用 Java8 新的时间 API 使用 Java8 新的时间 API
使用 Java8 新的时间 API简介Java8 面世以来已经 6 年了,许多人也开始使用起了 lambda,Stream<T>,Optional<T> 之类的新的语言特性,然而对于 Java8 提供的新的时间 AP
2018-09-04 rxliuli
下一篇 
SpringBoot 集成 WebSocket SpringBoot 集成 WebSocket
SpringBoot 集成 WebSocket SpringBoot 集成 WebSocket 场景 & 需求 前置知识 引入依赖 配置 SpringBoot WebSocket 支持 双向广播服务端 双向广播客户端 单向广播服务端
2018-09-03 rxliuli
  目录