当前位置: 首页 > news >正文

Spring前后端分离项目时间格式转换问题全局配置解决

hello,大家好,我是灰小猿!

在前后端分离的spring项目中,往往需要处理时间格式的属性的前后端传递问题,当下比较流行的作为时间格式属性的类型有date、LocalDateTime等,但是自jdk8以来,更推荐使用的是LocalDateTime格式,

但是在进行前后端数据传输时,我们可能会面临一个问题就是字符串格式的时间和LocalDateTime格式的时间转换问题,json的序列化和反序列化操作往往不能将这两种格式的时间进行直接转换,就会导致我们的代码报无法转换的错误,那么我们今天就来一一解决这些问题。

1、Controller中以参数形式直接接收date或LocalDateTime格式的时间报错解决

示例接口如下:

@GetMapping("/test")
public Result<String> testDate(@RequestParam LocalDateTime localDateTime) {return Result.success();
}

对于这种接口,如果不对时间格式进行处理,那么就会直接报字符串无法转换的错误

对此我们需要增加如下WebMvcConfigurer来控制时间字符的转换规则,如下配置支持字符串的时间向参数为Date和LocalDateTime格式转换。

/*** 解决前端请求中对于字符串类型的时间,主动转换为LocalDateTime或date格式*/
@Configuration
public class DateFormatterConfig implements WebMvcConfigurer {@Overridepublic void addFormatters(FormatterRegistry registry) {registry.addConverter(new StringToDateConverter());registry.addConverter(new StringToLocalDateTimeConverter());}/*** 字符串与date转换器*/static class StringToDateConverter implements Converter<String, Date> {@Overridepublic Date convert(@Nonnull String source) {if (ObjectUtil.isNull(source) || source.trim().isEmpty()) {return null;}String text = source.trim();Date date = DateUtils.parseDate(text);if (ObjectUtil.isNull(date)) {throw new IllegalArgumentException("日期格式不支持: " + text);}return date;}}/*** 字符串与LocalDateTime转换器*/static class StringToLocalDateTimeConverter implements Converter<String, LocalDateTime> {@Overridepublic LocalDateTime convert(@Nonnull String source) {if (ObjectUtil.isNull(source) || source.trim().isEmpty()) {return null;}String text = source.trim();Date date = DateUtils.parseDate(text);if (ObjectUtil.isNull(date)) {throw new IllegalArgumentException("日期格式不支持: " + text);}Instant instant = date.toInstant();ZoneId zoneId = ZoneId.systemDefault();return instant.atZone(zoneId).toLocalDateTime();}}
}

但是需要注意的是,这种配置只适用于时间类型参数直接放置在方法参数上的情况,但是往往我们的传参都会封装在对象内部,这种情况,就需要使用如下方式:

2、时间参数在请求和返回对象内部时时间格式转换解决

对于LocalDateTime类型,Jackson的默认序列化器会将其序列化为数组形式(如[2025,10,24,10,51,30,534759800])或者字符串(如"2025-10-24T10:51:30.5347598"),但是这通常不是我们想要的标准格式。

如果要全局配置LocalDateTime的序列化格式,我们可以使用Jackson的JavaTimeModule,并配合配置类来实现。

解决方案

1、添加依赖:确保项目中包含了Jackson的JavaTimeModule依赖,通常我们使用jackson-datatype-jsr310

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

2、配置全局日期格式:通过配置类自定义ObjectMapper,注册JavaTimeModule,并设置日期格式。

@Configuration
public class JacksonDateTimeConfig {private static final DateTimeFormatter DATETIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");private static final DateTimeFormatter TIME_FMT = DateTimeFormatter.ofPattern("HH:mm:ss");@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {return builder -> {// 关闭时间戳输出,使用字符串格式builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);// 序列化格式builder.serializers(new LocalDateTimeSerializer(DATETIME_FMT));builder.serializers(new LocalDateSerializer(DATE_FMT));builder.serializers(new LocalTimeSerializer(TIME_FMT));// 反序列化:优先使用自定义的 LocalDateTime 以支持多格式字符串JavaTimeModule javaTimeModule = new JavaTimeModule();javaTimeModule.addDeserializer(LocalDateTime.class, new MultiPatternLocalDateTimeDeserializer());javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DATE_FMT));javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(TIME_FMT));// 保留可扩展点SimpleModule extraModule = new SimpleModule();builder.modules(javaTimeModule, extraModule);};}/*** 兼容多种字符串日期格式的 LocalDateTime 反序列化,复用 DateUtils.parseDate。*/static class MultiPatternLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {@Overridepublic LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {String text = p.getValueAsString();if (text == null || text.trim().isEmpty()) {return null;}Date parsed = DateUtils.parseDate(text.trim());if (parsed == null) {// 回退:尝试按常见格式解析,交由默认反序列器兜底try {return LocalDateTime.parse(text.trim(), DATETIME_FMT);} catch (Exception ignore) {return (LocalDateTime) ctxt.handleWeirdStringValue(LocalDateTime.class, text, "无法解析为 LocalDateTime");}}Instant instant = parsed.toInstant();return instant.atZone(ZoneId.systemDefault()).toLocalDateTime();}}
}

当然,如果你的时间格式使用的是Date格式,也可以直接在application.yml中做如下配置即可:

# 设置全局日期时间格式
spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: Asia/Shanghai# 针对Java 8日期时间API的配置serialization:write-dates-as-timestamps: false

但是,对于LocalDateTime类型,仅仅使用spring.jackson.date-format可能不够,因为Jackson默认使用jackson-datatype-jsr310模块来处理Java8时间类型,而该模块默认使用ISO格式。所以,我们通常需要像上面那样自定义序列化器。

@JsonFormat注解

补充:如果上述配置仍然不生效,补救措施是直接在对应的属性上使用JsonFormat注解,具体如下:

import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;public class MyEntity {@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")private LocalDateTime createTime;// 省略 getter 和 setter
}

至此配置:我们项目中的LocalDateTime 类型字段返回给前端时就会是 "yyyy-MM-dd HH:mm:ss" 这样的标准格式,对于前端传递过来的字符类型的时间格式,也可以自动的帮我们转换为LocalDateTime 格式。省去了属性单独配置的工作。

我是灰小猿,我们下期见!

http://www.dtcms.com/a/565137.html

相关文章:

  • PCB设计<囫囵吞枣学习法>: 23_PCB设计之CAM文件输出
  • wordpress架构的网站如何做120急救网站
  • Linux-mount和umount
  • 【开题答辩全过程】以 飞途驾校报名管理系统为例,包含答辩的问题和答案
  • 北京网站设计确保代码符合w3cphotoshop做网站设计
  • 司马阅与麦腾科创达成生态战略合作,构建AI驱动的园区运营体系
  • 【设计模式笔记14】:抽象工厂模式概述
  • 前端身份识别与灰度发布完整指南
  • 使用扣子+飞书表格+影刀实现了自动化生成和发布 运营效率提升50倍
  • 智能做网站网页游戏传奇合击
  • h5科技 网站公众号小程序制作流程
  • 最小变更成本 vs 最小信息表达:第一性原理的比较
  • 在 Android 中使用协程(Coroutine)
  • 【​生命周期评价(LCA)】基于OpenLCA、GREET、R语言的生命周期评价方法、模型构建
  • 家用电器GB4706.1-2005质检报告办理
  • 有哪些网站主页做的比较好看汽车营销活动策划方案
  • 男女直接做的视频视频网站教育推广
  • 从HDFS NN报错看Flink+K8s+HDFS:基础、架构与问题关联
  • 一篇图文详解PID调参细节,实现PID入门到精通
  • 上位机与下位机(Host Computer/Slave Device)
  • SqlSugar查询字符串转成Int的问题
  • 网站免费做软件有哪些银川市建设诚信平台网站
  • Vue2 和 Vue3 生命周期的理解与对比
  • WinRAR“转换格式”功能详解:一键切换压缩包格式
  • 个人网站备案备注写什么济宁网站建设 企诺
  • 生活琐记(12)初七之月
  • 动态自优化的认知医疗层次激励编程技术架构(2025.10版)
  • 【005】使用DBeaver备份与还原mysql数据库
  • 生活方式与肥胖风险:多维度数据分析与预测模型研究
  • 南宁网站建设哪家好分销网站建设方案