目录

  • 1、背景
  • 2、序列化时间戳
  • 3、反序列化时间戳
  • 4、使用示例


1、背景

在SpringBoot开发web
应用微服务时,常用Date类型表示日期时间,JDK8之后,可以使用Instant类型来表示时间戳,并持久化到数据库中。也有直接使用Long类型存储日期时间或时间戳的,但这种方式存储到数据库后,对于DBA
或运维查询数据库时,不太友好,没法直接看出来是什么日期或时间。大多数时候会使用Instant类型来表示时间戳。

在前后端分离的开发架构中,对于日期时间类型,后端接口在返回给前端时,需要将Instant类型转换为前端需要的时间戳即长整型Long(可序列化的类型),而前端一般也会提交时间戳类型给后端,后端需要将时间戳的长整型Long
转换为Instant类型。即需要实现对日期时间进行序列化和反序列化。SpringBoot框架中,实现对日期时间进行序列化和反序列化,只需要实现相应的接口即可完成。

序列化是将一个对象转换成字节序列的过程,可以将这些字节序列存储在磁盘或通过网络传输。反序列化是将字节序列转换回对象的过程。

2、序列化时间戳

将Instant类型转换为前端需要的长整型Long,可以通过继承JsonSerializer类,实现serialize方法即可。

/*
 * Copyright (c) Bruce.CH 2022-2023. All rights reserved.
 */

package com.fandou.component.json;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.time.Instant;

/**
 * Instant序列化为Long类型
 *
 * @author Bruce.CH
 * @since 2023年08月19日
 */
public class InstantToLongSerializer extends JsonSerializer<Instant> {
    @Override
    public void serialize(Instant value, JsonGenerator generator, SerializerProvider serializers) throws IOException {
        // 通过JSON生成器,将要序列化的Instant类型对象即value的时间戳值写入为数值,即前端需要的长整型
        generator.writeNumber(value.toEpochMilli());
    }
}

3、反序列化时间戳

同样,将长整型Long转换为Instant类型,可以通过继承JsonDeserializer类,实现deserialize方法即可。

/*
 * Copyright (c) Bruce.CH 2022-2023. All rights reserved.
 */

package com.fandou.component.json;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;
import java.time.Instant;

/**
 * Long反序列化为Instant类型
 *
 * @author Bruce.CH
 * @since 2023年08月19日
 */
public class LongToInstantDeserializer extends JsonDeserializer<Instant> {
    @Override
    public Instant deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        // 从JSON初始化器中读取对应的长整型时间错值,使用Instant的ofEpochMilli初始化为Instant类型返回
        return Instant.ofEpochMilli(jsonParser.getValueAsLong());
    }
}

4、使用示例

使用@JsonSerialize注解或@JsonDeserialize注解标记需要序列化或反序列化的对象属性上,注解中的using属性值指定为步骤2或步骤3的序列化类或反序列化类型即可。在运行的过程中,SpringBoot
框架会自动完成日期时间的序列化和反序列化。

/*
 * Copyright (c) Bruce.CH 2022-2023. All rights reserved.
 */

package com.example.demo.vo;

import com.fandou.component.json.InstantToLongSerializer;
import com.fandou.component.json.LongToInstantDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import lombok.Getter;
import lombok.Setter;

import java.time.Instant;

/**
 * 用户VO对象
 *
 * @author Bruce.CH
 * @since 2022年11月05日
 */
@Setter
@Getter
public class User {
    /**
     * 主键id
     */
    private Long id;

    /**
     * 用户账号
     */
    private String userAccount;

    /**
     * 用户昵称
     */
    private String nickname;

    /**
     * 创建时间:使用@JsonSerialize注解和@JsonDeserialize注解实现创建时间属性的序列化和反序列化
     */
    @JsonSerialize(using = InstantToLongSerializer.class)
    @JsonDeserialize(using = LongToInstantDeserializer.class)
    private Instant createTime;
}