栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot全局时间格式统一处理和灵活处理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot全局时间格式统一处理和灵活处理

封装配置类
package com.yx.security.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import java.util.Objects;
import java.util.regex.Pattern;


@Configuration
public class JacksonObjectMapperCustomizer implements Jackson2ObjectMapperBuilderCustomizer {

    public static final DateTimeFormatter YEAR_MONTH = DateTimeFormatter.ofPattern("yyyy-MM");
    public static final DateTimeFormatter LOCAL_DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static final DateTimeFormatter HOUR_MINUTE = DateTimeFormatter.ofPattern("HH:mm");
    public static final DateTimeFormatter LOCAL_TIME = DateTimeFormatter.ofPattern("HH:mm:ss");
    public static final DateTimeFormatter LOCAL_DATE_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public static final Pattern yyyy_MM = Pattern.compile("\d{4}-\d{2}");
    public static final Pattern yyyy_MM_dd = Pattern.compile("\d{4}-\d{2}-\d{2}");
    public static final Pattern HH_mm = Pattern.compile("([0-1]?[0-9]|2[0-3]):([0-5][0-9])");
    public static final Pattern HH_mm_ss = Pattern.compile("([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])");
    public static final Pattern yyyy_MM_dd_HH_mm_ss = Pattern.compile("\d{4}-\d{2}-\d{2}([ ])([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])");

    @Override
    public void customize(Jackson2ObjectMapperBuilder builder) {
        // LocalDateTime序列化、反序列化
        builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(LOCAL_DATE_TIME));
        builder.deserializerByType(LocalDateTime.class, new FlexibleLocalDateTimeDeserializer(LOCAL_DATE_TIME));
        // LocalDate序列化、反序列化
        builder.serializerByType(LocalDate.class, new LocalDateSerializer(LOCAL_DATE));
        builder.deserializerByType(LocalDate.class, new FlexibleLocalDateDeserializer(LOCAL_DATE));
        // LocalTime序列化、反序列化
        builder.serializerByType(LocalTime.class, new LocalTimeSerializer(LOCAL_TIME));
        builder.deserializerByType(LocalTime.class, new FlexibleLocalTimeDeserializer(LOCAL_TIME));
        // Long序列化(序列化成字符串,因为精度问题,前端拿到数字类型会丢失精度)
        builder.serializerByType(Long.class, ToStringSerializer.instance);
    }


    
    public static class FlexibleLocalDateTimeDeserializer extends LocalDateTimeDeserializer {

        private FlexibleLocalDateTimeDeserializer() {
            this(LOCAL_DATE_TIME);
        }

        public FlexibleLocalDateTimeDeserializer(DateTimeFormatter formatter) {
            super(formatter);
        }

        @Override
        public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
            String timeStr = parser.getText();
            if (timeStr == null || (timeStr = timeStr.trim()).isEmpty()) return null;
            else if (yyyy_MM_dd_HH_mm_ss.matcher(timeStr).matches())
                return super.deserialize(parser, context);
            else if (yyyy_MM_dd.matcher(timeStr).matches())
                return parser.getCurrentName().toLowerCase().contains("end") ? LocalDate.parse(timeStr, LOCAL_DATE).atTime(LocalTime.MAX) : LocalDate.parse(timeStr, LOCAL_DATE).atStartOfDay();
            else if (yyyy_MM.matcher(timeStr).matches())
                return parser.getCurrentName().toLowerCase().contains("end") ? YearMonth.parse(timeStr, YEAR_MONTH).atEndOfMonth().atTime(LocalTime.MAX) : YearMonth.parse(timeStr, YEAR_MONTH).atDay(1).atStartOfDay();
            else throw new DateTimeParseException("时间字符串【" + timeStr + "'】格式不正确", timeStr, 0);
        }
    }

    
    public static class FlexibleLocalDateDeserializer extends LocalDateDeserializer {

        private FlexibleLocalDateDeserializer() {
            this(LOCAL_DATE);
        }

        public FlexibleLocalDateDeserializer(DateTimeFormatter dtf) {
            super(dtf);
        }

        @Override
        public LocalDate deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
            String timeStr = parser.getText();
            if (timeStr == null || (timeStr = timeStr.trim()).isEmpty()) return null;
            else if (yyyy_MM_dd.matcher(timeStr).find())
                return timeStr.length() > 10 ? LocalDateTime.parse(timeStr, LOCAL_DATE_TIME).toLocalDate() : LocalDate.parse(timeStr, LOCAL_DATE);
            else if (yyyy_MM.matcher(timeStr).matches())
                return parser.getCurrentName().toLowerCase().contains("end") ? YearMonth.parse(timeStr, YEAR_MONTH).atEndOfMonth() : YearMonth.parse(timeStr, YEAR_MONTH).atDay(1);
            else throw new DateTimeParseException("时间字符串【" + timeStr + "'】格式不正确", timeStr, 0);
        }
    }

    
    public static class FlexibleLocalTimeDeserializer extends LocalTimeDeserializer {

        private FlexibleLocalTimeDeserializer() {
            this(LOCAL_TIME);
        }

        public FlexibleLocalTimeDeserializer(DateTimeFormatter formatter) {
            super(formatter);
        }

        @Override
        public LocalTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {
            String timeStr = parser.getText();
            if (timeStr == null || (timeStr = timeStr.trim()).isEmpty()) return null;
            else if (HH_mm_ss.matcher(timeStr).matches()) return super.deserialize(parser, context);
            else if (HH_mm.matcher(timeStr).matches()) return LocalTime.parse(timeStr, HOUR_MINUTE);
            else throw new DateTimeParseException("时间字符串【" + timeStr + "'】格式不正确", timeStr, 0);
        }
    }

    
    public static class LocalDateFormatSerializer extends JsonSerializer {

        @Override
        public void serialize(TemporalAccessor temporalAccessor, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (Objects.isNull(temporalAccessor)) return;
            jsonGenerator.writeString(LOCAL_DATE.format(temporalAccessor));
        }
    }

    
    public static class YearMonthFormatSerializer extends JsonSerializer {

        @Override
        public void serialize(TemporalAccessor temporalAccessor, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (Objects.isNull(temporalAccessor)) return;
            jsonGenerator.writeString(YEAR_MONTH.format(temporalAccessor));
        }
    }

    
    public static class HourMinuteFormatSerializer extends JsonSerializer {

        @Override
        public void serialize(TemporalAccessor temporalAccessor, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (Objects.isNull(temporalAccessor)) return;
            jsonGenerator.writeString(HOUR_MINUTE.format(temporalAccessor));
        }
    }

    
    public static class LocalTimeFormatSerializer extends JsonSerializer {

        @Override
        public void serialize(TemporalAccessor temporalAccessor, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (Objects.isNull(temporalAccessor)) return;
            jsonGenerator.writeString(LOCAL_TIME.format(temporalAccessor));
        }
    }
}
灵活处理LocalDateTime类型
	// 入参格式: yyyy-MM-dd HH:mm:ss, yyyy-MM-dd, yyyy-MM
    @JsonDeserialize(using = JacksonObjectMapperCustomizer.FlexibleLocalDateTimeDeserializer.class)
    // 出参格式(默认): yyyy-MM-dd HH:mm:ss
    // 出参格式: yyyy-MM-dd
    // @JsonSerialize(using = JacksonObjectMapperCustomizer.LocalDateFormatSerializer.class)
    // 出参格式: yyyy-MM
    // @JsonSerialize(using = JacksonObjectMapperCustomizer.YearMonthFormatSerializer.class)
    private LocalDateTime startTime;
灵活处理LocalDate类型
	// 入参格式: yyyy-MM-dd HH:mm:ss, yyyy-MM-dd, yyyy-MM
    @JsonDeserialize(using = JacksonObjectMapperCustomizer.FlexibleLocalDateDeserializer.class)
    // 出参格式(默认): yyyy-MM-dd
    // 出参格式: yyyy-MM
    // @JsonSerialize(using = JacksonObjectMapperCustomizer.YearMonthFormatSerializer.class)
    private LocalDate startTime;
灵活处理LocalTime类型
	// 入参格式:HH:mm:ss, HH:mm
    @JsonDeserialize(using = JacksonObjectMapperCustomizer.FlexibleLocalTimeDeserializer.class)
    // 出参格式(默认): HH:mm:ss
    // 出参格式: HH:mm
    @JsonSerialize(using = JacksonObjectMapperCustomizer.HourMinuteFormatSerializer.class)
    private LocalTime startTime;
命名小细节

当变量名不包含end字符串时, 默认填充起始时间, 反之填充最大时间,

小结

时间处理封装的并不算彻底, 但足够解决大部分需求, 封装不一定越多越好, 实用就行。
如不满足业务需求, 可自行扩展。
如有不完善的地方或错误, 请评论点出或联系我及时纠正, 谢谢。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1032758.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号