15 时间格式的转换

15 时间格式的转换

|-------------|------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|---|
| 方向 | 技术 | 控制方式 | 关键点 |
| 前端 → 后端 | 表单提交 (application/x-www-form-urlencoded) | 1.注解 :@DateTimeFormat(pattern = "yyyy-MM-dd") 2.全局配置 :spring.mvc.format.date=yyyy-MM-dd 3. 代码定制 : addFormatters中重写Formatter的parse(String,Locale) 方法 | 后端解析格式必须与前端发送的字符串格式一致。三种方式均可,优先级:注解 > 代码定制 > 全局配置。 |
| 前端 → 后端 | JSON 提交 (@RequestBody) | 1.注解 : @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") 2.全局配置 : spring.jackson.date-format=yyyy-MM-dd和 spring.jackson.time-zone=GMT+8 | 后端解析格式必须与 JSON 中的字符串格式一致。Formatter对此场景无效 。 | |
| 后端 → 前端 | JSON 响应 (@ResponseBody) | 1.注解 : @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") 2.全局配置 :spring.jackson.date-format=yyyy-MM-dd和spring.jackson.time-zone=GMT+8 | 后端可以定义任意友好的展示格式,前端直接接收字符串并展示。Formatter对此场景无效 。 |
| 后端 → 前端 | 视图渲染 (如 Thymeleaf, JSP) | 代码定制 : addFormatters中重写Formatter的print(Date, Locale) 方法 | 后端可以定义任意格式。当Date对象被直接渲染到视图模板时,Spring MVC 会使用此方法将其格式化为指定字符串。这是Formatter独有的场景,用于统一页面上所有日期的显示格式。 |

注:对于Jackson库可以换成其他Json库,比如Fastjson,此时注解@JsonFormat应该换成Fastjson对应的@JSONField 注解。换了之后,除了注解和库变了,其他的规则同@JsonFormat。如何换库,具体见 ++14 SpringBoot整合SpringMVC++14.2.3。

15.1 前端 → 后端 (表单提交)

  1. 场景:用户通过 标签提交数据,其中包含日期。

  2. 前端行为: 会将日期以 yyyy-MM-dd 格式的字符串发送给后端。

  3. 后端解析方式:

  • 方式一 (全局配置):在 application.yml 中配置 spring.mvc.format.date。

    spring:
    mvc:
    format:
    date: yyyy-MM-dd # 必须与前端传来的格式一致

  • 方式二 (局部注解):在实体类的日期字段上使用 @DateTimeFormat 注解。

    public class User {
    @DateTimeFormat(pattern = "yyyy-MM-dd") // 必须与前端传来的格式一致
    private Date birthday;
    // ...
    }

  • 方式三(代码定制):创建一个配置类实现WebMvcConfigurer接口,并在重写addFormatters这个方法。修改这个方法中的 Formatter 的 parse(String, Locale) 方法。

  1. 优先级:@DateTimeFormat 注解 (局部) > 代码定制 > spring.mvc.format.date (全局)。
  2. 结论:如果你想使用除 yyyy-MM-dd 之外的格式(例如 yyyy/MM/dd),你必须在前端通过 JavaScript 将日期字符串格式化为你想要的格式,然后再提交给后端。后端的配置或注解必须与前端最终发送的格式保持一致。

15.2 前端 → 后端 (JSON 提交)

  1. 场景:前端通过 AJAX (如 fetch, axios) 发送 JSON 数据给后端,后端使用 @RequestBody 注解接收。
  2. 前端行为:前端构造一个 JSON 对象,其中日期是一个字符串,例如 {"username": "张三", "birthday": "2025-11-19"}。
  3. 后端解析方式:
  • 方式一 (全局配置):在 application.yml 中配置 Jackson 的日期格式。

    spring:
    jackson:
    date-format: yyyy-MM-dd # 必须与 JSON 中的日期字符串格式一致
    time-zone: GMT+8

  • 方式二 (局部注解):在实体类的日期字段上使用 @JsonFormat 注解。

    public class User {
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") // 必须与 JSON 中的日期字符串格式一致
    private Date birthday;
    // ...
    }

  1. 优先级:@JsonFormat 注解 (局部) > spring.jackson.date-format (全局)。

  2. 错误示例:如果 JSON 中的日期是 "2025-11-19",而你的配置或注解是 yyyy/MM/dd,就会遇到下面这个提到的错误:

    JSON parse error: Cannot deserialize value of type java.util.Date from String "2025-11-19": expected format "yyyy/MM/dd"

15.3 后端 → 前端 (JSON 响应)

  1. 场景:后端通过 @ResponseBody 注解返回一个 Java 对象(如 User),Spring Boot 会自动将其转换为 JSON 字符串。
  2. 后端行为:Spring Boot 使用 Jackson 库进行序列化。
  3. 控制 JSON 格式的方式:
  • 方式一 (全局配置):在 application.yml 中配置 spring.jackson.date-format。这会影响所有 Date 类型字段的序列化。
  • 方式二 (局部注解):在实体类的日期字段上使用 @JsonFormat 注解。这只影响该字段的序列化。
  1. 注意:后端到前端 日期格式想是什么就是什么 都可以正常转。
  2. 原因:在这个场景中,后端是 "格式的定义者"。Jackson 会按照你指定的格式(通过 @JsonFormat 或全局配置),将 Date 对象转换成一个字符串。前端接收到的就是这个格式化好的字符串,它不需要进行任何解析,直接展示即可。

15.4 后端 → 前端(视图渲染)

  1. 场景:后端 Controller 方法返回一个逻辑视图名称(如 "user/profile")和一个包含 Date 对象的模型(Model)。Spring MVC 会将模型数据传递给视图模板(如 Thymeleaf, FreeMarker, JSP)进行渲染,最终生成 HTML 页面返回给前端。

  2. 后端行为:Spring MVC 在将模型中的 Date 对象传递给视图模板之前,会检查是否存在一个注册的 Formatter。如果存在,它会调用该格式化器的 print 方法。

  3. 控制日期显示格式的方式:
    方式一 (全局代码配置):通过实现 WebMvcConfigurer 接口并重写 addFormatters 方法,注册一个自定义的 Formatter。在该格式化器的 print(Date date, Locale locale) 方法中,定义你希望的日期字符串格式(如 "yyyy年MM月dd日")。

    @Override
    public void addFormatters(FormatterRegistry registry) {
    registry.addFormatter(new Formatter<Date>() {
    @Override
    public String print(Date date, Locale locale) {
    // 当Date对象被渲染到视图时,格式化为 "yyyy年MM月dd日"
    return new SimpleDateFormat("yyyy年MM月dd日").format(date);
    }

    复制代码
         // parse方法在此场景下不发挥作用
         @Override
         public Date parse(String text, Locale locale) throws ParseException {
             return null;
         }
     });

    }

  4. 后端可以定义任意格式。

相关推荐
问道飞鱼17 小时前
【前端知识】从前端请求到后端返回:Gzip压缩全链路配置指南
前端·状态模式·gzip·请求头
seven_7678230981 天前
DevUI表单引擎实战:可配置化动态表单与多级联动设计
状态模式·devui·matechat
泽济天下1 天前
【经验分享】基于Spring Boot 4.0快速实现最简版的OAuth2 Server和Client
spring boot·springboot·oauth2
重生之我在番茄自学网安拯救世界1 天前
网络安全中级阶段学习笔记(二):网络安全暴力破解学习重点笔记
状态模式·网安基础
小雨青年2 天前
MateChat 进阶实战:打造零后端、隐私安全的“端侧记忆”智能体
前端·华为·ai·华为云·状态模式
她说..2 天前
Java AOP完全指南:从原理到实战(全套知识点+场景总结)
java·开发语言·spring·java-ee·springboot
兩尛2 天前
项目1相关八股
状态模式
千寻技术帮2 天前
10414_基于SpringBoot的家乡农产品销售平台
源码·springboot·商城·文档·农产品
一 乐2 天前
数码商城系统|电子|基于SprinBoot+vue的数码商城系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·springboot