@DateTimeFormat、@JsonFormat、@JSONField区别及用法
推荐写法:
@JSONField(format = "yyyy-MM-dd HH:mm:ss")@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDate birthday;
前端读取数据库日期字段时使用 @JsonFormat和@JSONField 可以将时间戳转为格式化的日期数据。
前端使用JSON提交时用@JsonFormat和@JSONField
前端使用Form提交时用@DateTimeFormat
@DateTimeFormat
@DateTimeFormat 是 Spring 框架自带的注解(包路径:org.springframework.format.annotation),主要用于前端向后台传递字符串类型的日期时间时,将其转换为 Java 中的日期时间对象(如 Date、LocalDateTime 等)。
核心功能
- 限制前端传入的日期时间字符串格式,若格式不匹配,Spring 会抛出转换异常(如 MethodArgumentTypeMismatchException)。
- 即使不加该注解,Spring 也能解析部分默认格式的时间字符串(如 yyyy/MM/dd),但通过 pattern 属性可自定义格式,更灵活。
常用属性
- pattern:自定义日期时间格式,例如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss。
- style:通过预定义的风格指定格式(较少用),如 S- 表示短日期格式。
- iso:使用 ISO 标准格式(如 ISO.DATE 对应 yyyy-MM-dd)。
示例
@RestControllerpublic class UserController {// 前端传入 "2023-10-01" 时,自动转换为 Date 类型@GetMapping("/query")public String queryByDate(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date) {return "查询日期:" + date;}}
@JsonFormat
@JsonFormat 是 Jackson 库(Java 常用的 JSON 解析库)提供的注解(包路径:com.fasterxml.jackson.annotation),主要用于JSON 序列化和反序列化时,指定日期时间的格式。
核心功能
- 序列化:将 Java 中的日期时间对象(如 Date、LocalDateTime)转换为指定格式的 JSON 字符串(如后台返回给前端时)。
- 反序列化:将 JSON 字符串中的日期时间转换为 Java 对象(如前端通过 JSON 传递时间给后台时)。
- 需注意时区问题:默认时区为 GMT,若需适配北京时间,需指定 timezone = "GMT+8"。
常用属性
- pattern:自定义日期时间格式(同 @DateTimeFormat)。
- timezone:指定时区,如 GMT+8(北京时间)。
- shape:指定序列化后的形态(如 Shape.STRING 强制转换为字符串)。
示例
public class User {// 序列化时,Date 转换为 "2023-10-01 12:00:00"(北京时间)@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")private Date createTime;// getter/setter}
当该类被序列化为 JSON 时,createTime 会以 2023-10-01 12:00:00 格式返回给前端。
@JsonField
@JsonField 是阿里巴巴的 Fastjson 库(另一个常用的 JSON 解析库)提供的注解(包路径:com.alibaba.fastjson.annotation),功能与 @JsonFormat 类似,用于Fastjson 处理 JSON 序列化和反序列化。
核心功能
- 除了格式化日期时间外,还可用于指定 JSON 字段的名称、序列化顺序、是否参与序列化等。
- 仅在项目中使用 Fastjson 作为 JSON 解析库时生效。
常用属性
- format:日期时间格式化格式(类似 pattern)。
- name:指定 JSON 中的字段名(如 Java 字段为 createTime,JSON 中显示为 create_time)。
- ordinal:指定序列化时的字段顺序(值越小越靠前)。
- serialize:是否参与序列化(true/false)。
示例
public class Order {// Java 字段为 createTime,JSON 中显示为 create_time,格式为 "2023-10-01"@JsonField(name = "create_time", format = "yyyy-MM-dd")private Date createTime;// getter/setter}
当用 Fastjson 序列化 Order 对象时,createTime 会被转换为 {"create_time": "2023-10-01"}。
三者核心区别总结
维度 | @DateTimeFormat | @JsonFormat | @JsonField |
所属框架 | Spring 自带 | Jackson 库 | Fastjson 库 |
核心用途 | 前端字符串 → Java 日期对象(请求参数绑定) | JSON 与 Java 日期对象互转(序列化 / 反序列化) | JSON 与 Java 日期对象互转(序列化 / 反序列化) |
适用场景 | 非 JSON 格式的请求参数(如表单、URL 参数) | 使用 Jackson 处理 JSON 时 | 使用 Fastjson 处理 JSON 时 |
额外功能 | 仅格式化日期转换 | 支持时区设置 | 支持自定义 JSON 字段名、排序等 |
实际开发中的配合使用
- 若前端通过表单或 URL 参数传递日期,用 @DateTimeFormat 处理入参。
- 若前端通过JSON 格式传递日期或后台返回 JSON,根据项目使用的 JSON 库选择:
- 用 Jackson 则加 @JsonFormat(需指定时区)。
- 用 Fastjson 则加 @JsonField。
- 例如:同一个接口可能同时需要处理表单入参和 JSON 响应,此时需同时使用 @DateTimeFormat 和 @JsonFormat(或 @JsonField)。