三个注解,到底该用哪一个?别再傻傻分不清了!

先给JYM看一个项目中实体类的同一字段的不同注解

上述图中,三个实体类中对于时间的格式化都用了不同的注解方法,写法是没问题的,但是究竟用哪个呢?是不是一个头三个大了,那么我们今天就分析分析这三个时间格式化的不同之处。

一、认识三大"时间格式化"

  1. @DateTimeFormat (Spring 的专属表单时间)

    • 来源: Spring Framework (org.springframework.format.annotation)

    • 核心任务: 专门解决 HTTP 请求中日期时间字符串如何转换成后端 Java DateLocalDateTime 等类型的问题。 简单说,就是处理入参绑定

    • 主要用处:

      • 前端通过 application/x-www-form-urlencoded 或 multipart/form-data (表单提交) 传递的时间参数。
    • 工作方式: 它告诉 Spring MVC:"当你在 Controller 方法参数上或者接收参数的 JavaBean 属性上看到我时,请按照我指定的格式,把前端传过来的那个时间字符串,变成对应的 Java 日期时间对象!"

    • 比如:

      java 复制代码
      @PostMapping("/user")
      public String createUser(@ModelAttribute User user) {
          // ... 处理 user
      }
      
      public class User {
          @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") // 告诉Spring如何把字符串变Date
          private Date birthday;
          // ... 其他字段
      }
      • 假设前端表单提交了一个 birthday=2023-10-25 14:30:00,Spring 看到 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss"),就知道该用这个格式把字符串变成 Date 对象塞进 user.birthday
    • 关键点:它只管前端字符串 -> 后端 Java 对象 (反序列化),不管后端对象怎么变成字符串返回给前端!

  2. @JSONField (Fastjson 的日期格式)

    • 来源: 阿里巴巴的 Fastjson 库 (com.alibaba.fastjson.annotation)

    • 核心任务: 专门控制 Java 对象在 使用 Fastjson 库 进行序列化 (Java对象 -> JSON字符串) 和反序列化 (JSON字符串 -> Java对象) 时,日期时间字段的格式化行为。

    • 主要用处: 任何使用 Fastjson 进行 JSON 转换的场景。

      • 后端接口返回 JSON 数据给前端。
      • 后端接收前端发送的 JSON 请求体。
      • 使用 Fastjson 进行其他对象到 JSON 的转换。
    • 工作方式: 它贴在 Java 类的日期字段上,对 Fastjson 说:"序列化这个字段成 JSON 时,请按 format指定的格式输出字符串;反序列化 JSON 字符串到这个字段时,也请按 format 指定的格式去解析成 Date 对象。"

    • 比如:

      java 复制代码
      public class Order {
          @JSONField(format = "yyyy-MM-dd HH:mm") // 告诉Fastjson怎么序列化和反序列化
          private Date createTime;
          // ... 其他字段
      }
      • 序列化 (后端 -> 前端 JSON): order.createTime 是一个 Date 对象,Fastjson 会按 "yyyy-MM-dd HH:mm" 格式把它变成字符串,如 "2023-10-25 14:30" 写入 JSON。
      • 反序列化 (前端 JSON -> 后端): 如果前端 POST 一个 JSON 过来 {"createTime": "2023-10-25 14:30"}, Fastjson 会按 "yyyy-MM-dd HH:mm" 格式把这个字符串解析成 Date 对象,塞进 order.createTime
    • 关键点:它只对 Fastjson 生效,既管序列化 (出参) 也管反序列化 (入参)。

  3. @JsonFormat (Jackson 的日期格式)

    • 老家: Jackson 库 (com.fasterxml.jackson.annotation)

    • 核心任务: 专门控制 Java 对象在 使用 Jackson 库 (Spring Boot 默认使用它!) 进行序列化 (Java对象 -> JSON字符串) 和反序列化 (JSON字符串 -> Java对象) 时,日期时间字段的格式化行为。 功能上和 @JSONField 非常相似,只是服务的库不同。

    • 主要用处: 任何使用 Jackson 进行 JSON 转换的场景 (尤其在 Spring Boot 项目中非常普遍)。

      • @RestController 返回的对象自动转 JSON。
      • 接收 @RequestBody 注解的 JSON 参数。
      • 使用 ObjectMapper 进行手动 JSON 转换。
    • 工作方式:@JSONField 几乎一样,贴在字段上,告诉 Jackson 序列化和反序列化这个日期字段时使用的格式、时区等。

    • 比如:

      java 复制代码
      public class Product {
          @JsonFormat(pattern = "yyyy/MM/dd", timezone = "GMT+8") // 告诉Jackson
          private Date expiryDate;
          // ... 其他字段
      }
      • 序列化 (后端 -> 前端 JSON): Jackson 会把 product.expiryDate"yyyy/MM/dd" 格式和东八区时区输出,如 "2024/12/31"
      • 反序列化 (前端 JSON -> 后端): 前端传 {"expiryDate": "2024/12/31"}, Jackson 会按 "yyyy/MM/dd" 格式解析成 Date 对象 (并考虑时区)。
    • 关键点:它只对 Jackson 生效,是 Spring Boot 生态下的 JSON 格式化主力,既管序列化也管反序列化。

二、对照表看吧就

特性 @DateTimeFormat (Spring) @JSONField (Fastjson) @JsonFormat (Jackson)
所属库/框架 Spring Framework 阿里巴巴 Fastjson FasterXML Jackson
主要职责 入参绑定 (字符串 -> Date) JSON 序列化与反序列化 JSON 序列化与反序列化
作用方向 单向 (仅入参反序列化) 双向 (序列化 + 反序列化) 双向 (序列化 + 反序列化)
关键场景 表单提交 / URL 查询参数 使用 Fastjson 处理 JSON 的接口 使用 Jackson (Spring Boot默认) 处理 JSON 的接口
常用属性 pattern (格式) format (格式), name (别名) 等 pattern (格式), timezone (时区), locale (地区) 等
是否处理出参
是否处理入参 是 (仅特定来源) 是 (JSON 请求体) 是 (JSON 请求体)

三、到底该用谁?

选择的关键在于弄清楚你当前要解决的是什么问题 ,以及你的项目用了哪个 JSON 库

  1. 解决前端表单或 URL 参数 (application/x-www-form-urlencoded, multipart/form-data, GET 参数) 中的日期字符串转换成后端 Java 对象的问题?

    • 果断用 @DateTimeFormat
    • 这是它的本职工作。把它贴在 Controller 方法参数对象或 @ModelAttribute 对象的日期字段上。它只负责"进"。
  2. 解决后端 Java 对象中的日期字段,在返回给前端的 JSON 中如何格式化?或者前端传过来的 JSON 请求体中的日期字符串如何解析成 Java 对象?

    • 看项目使用的 JSON 库:
      • 如果项目主要使用 Fastjson: 用 @JSONField(format = "你的格式")
      • 如果项目使用 Spring Boot 默认的 Jackson 或明确使用了 Jackson: 用 @JsonFormat(pattern = "你的格式"[, timezone = "时区"])
    • 这两个注解都既管"进"(JSON请求体->Java对象)也管"出"(Java对象->JSON响应)
  3. 一个字段既要接收表单日期,又要作为 JSON 返回?

    • 这太常见了!比如一个 User 对象,用户注册时通过表单提交生日,查询用户信息时又需要把生日以特定格式返回 JSON。
    • 解决方案:@DateTimeFormat + @JsonFormat (或 @JSONField,根据 JSON 库选) 同时使用!**
    java 复制代码
    public class User {
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        @JsonFormat(pattern = "yyyy/MM/dd", timezone = "GMT+8")
        private Date birthday;
        // ... 其他字段
    }

搞清楚这三个注解的"势力范围"和"工作职责",以后处理日期格式化就能得心应手,再也不会被乱七八糟的时间格式气得抓狂了!下次同事再搞混,记得把本文甩给他看哟!

相关推荐
你的人类朋友22 分钟前
【Node.js】什么是Node.js
javascript·后端·node.js
David爱编程2 小时前
面试必问!线程生命周期与状态转换详解
java·后端
LKAI.2 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi
Victor3563 小时前
Redis(11)如何通过命令行操作Redis?
后端
Victor3563 小时前
Redis(10)如何连接到Redis服务器?
后端
他日若遂凌云志4 小时前
深入剖析 Fantasy 框架的消息设计与序列化机制:协同架构下的高效转换与场景适配
后端
快手技术4 小时前
快手Klear-Reasoner登顶8B模型榜首,GPPO算法双效强化稳定性与探索能力!
后端
用户49055816081255 小时前
当控制面更新一条 ACL 规则时,如何更新给数据面
后端
林太白5 小时前
Nuxt.js搭建一个官网如何简单
前端·javascript·后端