所有分类
  • 所有分类
  • 未分类

SpringBoot–全局处理LocalDateTime响应格式(时间戳)

简介

说明

项目我们经常会有前后端时间转换的场景,比如:创建时间、更新时间等。一般情况下,前后端使用时间戳或者年月日的格式进行传递。

如果后端收到了前端的参数每次都手动转化为想要的格式,后端每次将数据传给前端时都手动处理为想要的格式实在是太麻烦了。

基于如上原因,本文用示例介绍SpringBoot全局格式配置,将LocalDateTime自动转化为时间戳格式传给前端。

备注

有人说,可以这样配置:

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    serialization:
      write-dates-as-timestamps: true

  • 这种配置只适用于Date这种,不适用于LocalDateTime等。

前提

本文为了测试,都前端以时间戳的方式将时间传到后端,参考此文

配置如下

package com.knife.example.common.format.request;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;

import java.time.*;
import java.time.format.DateTimeFormatter;

@Configuration
public class LocalDateTimeConfig {

    @Bean
    public Converter<String, LocalDateTime> localDateTimeConverter() {
        return new LocalDateTimeConverter();
    }

    public static class LocalDateTimeConverter implements Converter<String, LocalDateTime> {
        @Override
        public LocalDateTime convert(String text) {
            long timestamp = Long.parseLong(text);
            return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp),
                    ZoneId.systemDefault());
        }
    }
}

局部方案:自定义序列化器

自定义序列化器

package com.knife.example.common.format.response;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

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

public class LocalDateTimeConverter {
    // 序列化实现
    public static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
                throws IOException {
            if (value != null) {
                long timestamp = value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
                gen.writeNumber(timestamp);
            }
        }
    }

    // 反序列化实现
    public static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext)
                throws IOException {
            long timestamp = p.getValueAsLong();
            if (timestamp > 0) {
                return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
            } else {
                return null;
            }
        }
    }
}

VO

package com.knife.example.business.product.vo;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.knife.example.common.format.request.LocalDateTimeConfig;
import com.knife.example.common.format.response.LocalDateTimeConverter;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.time.LocalDateTime;

@Data
@ApiModel("商品响应类")
public class ProductVO {
    @ApiModelProperty("id")
    private Long id;

    @ApiModelProperty("名字")
    private String name;

    @ApiModelProperty("库存数量")
    private Integer stockQuantity;

    @ApiModelProperty("创建时间")
    @JsonSerialize(using = LocalDateTimeConverter.LocalDateTimeSerializer.class)
    private LocalDateTime createTime;
}

测试

后端输出

2021-09-16T19:20:34.876

注意事项

本法只能用于将数据转为时间戳响应给前端,无法自动解析前端传进来的时间戳(无论是直接接收还是通过实体类接收都不行)。

此方法不仅可以用于返给前端数据,也可以用于后端的转换:使用jackson的ObjectMapper的writeValueAsString方法将对象转为json字符串。而下边的全局配置就不可以。

全局方案1:配置Jackson+自定义序列化

此内容查看价格为1.5积分,VIP免费,请先
0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录