@DateTimeFormat和@JsonFormat注解的用法及說明
一、快速入門
先說總結(jié):如果你要在實(shí)體類的屬性上加注解,那么你這倆注解都加上,啥問題都沒有。
1.1、準(zhǔn)備工作
定義一個(gè)pojo,它有兩個(gè) java.util.Date 類型的屬性 createDate和uploadDate。
現(xiàn)在屬性上什么注解都沒加,接著往下走看效果。
public class Student{
private Integer id;
private String name;
private Date createDate;
private Date uploadDate;
// 省略get和set方法
}
定義一個(gè)Controller
@RequestMapping("/student")
@RestController
public class StudentController {
@GetMapping("/test")
public Student test(Student student) {
System.out.println("前端傳來的日期:" + student.getCreateDate());
// 將前端傳來的日期格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = sdf.format(student.getCreateDate());
System.out.println("格式化后的日期:"+date);
// 傳一個(gè)當(dāng)前日期給前端,想看看是什么格式的
Student stu = new Student();
stu.setCreateDate(new Date());
return stu;
}
}
在apipost傳參測(cè)試,訪問 /student/test ,并傳入?yún)?shù):2018-08-02 22:05:55,發(fā)現(xiàn)并不能訪問成功,會(huì)拋出400異常,因?yàn)閭魅氲膮?shù)是 String 類型的,而用來接收參數(shù)的 DateVo 的 date 屬性是 java.util.Date 類型的,類型無法轉(zhuǎn)換。
怎么辦呢?請(qǐng)往下看,也就是入?yún)⒏袷交?/p>

1.2、入?yún)⒏袷交ㄇ岸藗鲄⒌胶蠖耍?/h3>
解決辦法就是在接收參數(shù)的pojo類上的隊(duì)友參數(shù)屬性上加上注解:
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
加完之后的pojo類:
public class Student{
private Integer id;
private String name;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createDate;
private Date uploadDate;
// 省略get和set方法
}
再測(cè)試,這樣就能請(qǐng)求成功,后端就能接收前端傳的參數(shù)了,結(jié)果如下:
控制臺(tái)輸出:
前端傳來的日期:Thu Aug 02 22:05:55 CST 2018 格式化后的日期:2018-08-02 22:05:55
響應(yīng):
{
"id": null,
"name": null,
"createDate": "2024-08-13T11:37:59.022+00:00",
"uploadDate": null
}

請(qǐng)注意:
這樣請(qǐng)求成功后,后端就能接收前端傳的參數(shù)了,但后端接收到的日期時(shí)間的格式還是需要自己再手動(dòng)轉(zhuǎn)換一下。因?yàn)?@DateTimeFormat 注解的 pattern 屬性值指定的日期時(shí)間格式并不是將要轉(zhuǎn)換成的日期格式,這個(gè)指定的格式是和傳入的參數(shù)對(duì)應(yīng)的,假如注解為:
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss")
則傳入的參數(shù)應(yīng)該是這樣的:2018/08/02 22:05:55,如果傳入2018/08/02就會(huì)拋出400異常。
1.3、出參格式化(后端返回給前端)
在上述示例中,調(diào)用接口的返回結(jié)果為:
{
"id": null,
"name": null,
"createDate": "2024-08-13T11:37:59.022+00:00",
"uploadDate": null
}
這個(gè)格式并不是我們想要的,那么如何將其進(jìn)行格式化?這時(shí)就需要用到 jackson 的 @JsonFormat 注解。
改造 Student:
public class Student{
private Integer id;
private String name;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createDate;
private Date uploadDate;
// 省略get和set方法
}
這樣響應(yīng)的日期就是正確的。
{
"id": null,
"name": null,
"createDate": "2024-08-13 19:49:28",
"uploadDate": null
}
1.4、如果是請(qǐng)求體@RequestBody傳參
pojo的屬性類型是Date,不加@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss")這個(gè)一樣能接收到前端傳來的日期。那么只能傳 "createDate":"2018-08-02 ",因?yàn)镈ate不支持時(shí)分秒,沒法接收"createDate":"2018-08-02 22:11:05"這種,如果傳帶時(shí)分秒的,用@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss")也不管用。

如果你想在請(qǐng)求體中,傳帶時(shí)分秒的,并且返回時(shí)分秒的??梢匀缦虏僮鳎簿褪瞧匠i_發(fā)最常用的。
pojo類:
public class Student{
private Integer id;
private String name;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")// 這個(gè)加不加不影響結(jié)果,但是不能只有它,沒有下邊的JsonForm注解。但是可以只有下邊的JsonForm注解。
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createDate;
private Date uploadDate;
// 省略get和set方法
}
稍微改了下剛才的Controller
@GetMapping("/test")
public Student test(@RequestBody Student student) {
System.out.println("前端傳來的日期:" + student.getCreateDate());
// 將前端傳來的日期格式化后返回
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = sdf.format(student.getCreateDate());
System.out.println("格式化后的日期:"+date);
// 返回前端的日期
Student stu = new Student();
stu.setCreateDate(student.getCreateDate());
return stu;
}

注意:如果是請(qǐng)求體接收參數(shù),只加@JsonForm注解,而不寫@DateTimeFormat注解可以正常接收。
public class Student{
private Integer id;
private String name;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createDate;
private Date uploadDate;
// 省略get和set方法
}

但如果是剛才的請(qǐng)求參數(shù)問題,不能只寫@JsonForm注解,而不寫@DateTimeFormat注解。這樣會(huì)報(bào)400,也就是pojo如下,響應(yīng)結(jié)果如下圖。
public class Student{
private Integer id;
private String name;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createDate;
private Date uploadDate;
// 省略get和set方法
}
記得在Controller里吧@requestBody去掉

二、解釋這兩個(gè)注解
1、@JsonFormat
@JsonFormat 是 Jackson 庫中的注解,用于在序列化和反序列化過程中控制日期和時(shí)間的格式。
主要用于控制如何將 Java 對(duì)象中的日期時(shí)間格式化為 JSON 輸出(即從后端到前端的格式化),適用于序列化和反序列化 JSON 數(shù)據(jù),通常用在實(shí)體類中的日期字段上
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date time;
2、@DateTimeFormat
@DateTimeFormat 是 Spring 框架中用于處理日期和時(shí)間格式的注解,主要用于將前端傳來的日期時(shí)間字符串轉(zhuǎn)換為 Java 對(duì)象(即從前端到后端的解析),適用于處理 Web 請(qǐng)求中的日期時(shí)間參數(shù),通常與 @RequestParam、@PathVariable 等注解結(jié)合使用。
1、用途:
@DateTimeFormat 用于格式化日期和時(shí)間,確保請(qǐng)求參數(shù)能夠按照指定的格式被解析。
只對(duì) @RequestParam 和 @PathVariable 類型的參數(shù)有效,而對(duì) @RequestBody 無效。對(duì) @RequestBody 的日期格式化需要用到 @JsonFormat。
支持的格式:
可以指定日期和時(shí)間的格式,例如 "yyyy-MM-dd"、"yyyy-MM-dd HH:mm:ss" 等。
2、示例代碼:
后端代碼(Spring Boot Controller)
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
import java.time.LocalDateTime;
@RestController
public class DateController {
@GetMapping("/date")
public String getDate(
@RequestParam("date")
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date,
@RequestParam("dateTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime dateTime) {
return "Date: " + date + ", DateTime: " + dateTime;
}
}
API 測(cè)試代碼(使用 Apipost)
假設(shè)你啟動(dòng)了上述 Spring Boot 應(yīng)用,下面是如何在 Apipost 中測(cè)試這個(gè)接口:
GET 請(qǐng)求 URL:
http://localhost:8080/date?date=2024-08-13&dateTime=2024-08-13%2015:45:30
響應(yīng):
Date: 2024-08-13, DateTime: 2024-08-13T15:45:30
特別注意
1、這兩者的注解一般聯(lián)合使用
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone="GMT+8") private Date time;
一般系統(tǒng)都是前后交互
對(duì)此總結(jié)如下:
@JsonFormat: 用于序列化和反序列化 JSON 數(shù)據(jù)中的日期時(shí)間字段,確保數(shù)據(jù)從后端到前端的一致性
@DateTimeFormat: 用于解析和格式化 Web 請(qǐng)求中的日期時(shí)間參數(shù),確保數(shù)據(jù)從前端到后端的正確處理
2、注意2
- 對(duì) URL 參數(shù)有效:
@DateTimeFormat常用于 URL 參數(shù)的解析例如,@RequestParam中的日期參數(shù)會(huì)受到@DateTimeFormat的影響 - 對(duì)請(qǐng)求體中的參數(shù): 在請(qǐng)求體中,
@DateTimeFormat的直接作用有限,如果請(qǐng)求體中的日期時(shí)間字段是 JSON格式的,@DateTimeFormat不會(huì)直接影響解析,在這種情況下,通常使用@JsonFormat來指定 JSON 中的日期時(shí)間格式
如果需要在請(qǐng)求體中解析日期時(shí)間,應(yīng)該確保 JSON 轉(zhuǎn)換器(如 Jackson)能夠正確處理日期格式。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java?Thread.join()方法使用詳細(xì)解析
Thread.join()是Java多線程編程中的關(guān)鍵方法,用于確保線程執(zhí)行順序和數(shù)據(jù)完整性,下面這篇文章主要介紹了Java?Thread.join()方法使用的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2026-01-01
Java設(shè)計(jì)模式之Builder建造者模式
這篇文章主要為大家詳細(xì)介紹了Java設(shè)計(jì)模式之Builder建造者模式的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
詳解在spring boot中配置多個(gè)DispatcherServlet
本篇文章主要介紹了詳解在spring boot中配置多個(gè)DispatcherServlet,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-03-03
SpringMVC + servlet3.0 文件上傳的配置和實(shí)現(xiàn)代碼
本篇文章主要介紹了SpringMVC + servlet3.0 文件上傳的配置和實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
springboot 基于Tomcat容器的自啟動(dòng)流程分析
這篇文章主要介紹了springboot 基于Tomcat容器的自啟動(dòng)流程分析,Spring通過注解導(dǎo)入Bean大體可分為四種方式,我們主要來說Import的兩種實(shí)現(xiàn)方法,需要的朋友可以參考下2020-02-02
springboot 默認(rèn)靜態(tài)路徑實(shí)例解析
這篇文章主要介紹了springboot 默認(rèn)靜態(tài)路徑實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
Java使用Instant時(shí)輸出的時(shí)間比預(yù)期少了八個(gè)小時(shí)
在Java中,LocalDateTime表示沒有時(shí)區(qū)信息的日期和時(shí)間,而Instant表示基于UTC的時(shí)間點(diǎn),本文主要介紹了Java使用Instant時(shí)輸出的時(shí)間比預(yù)期少了八個(gè)小時(shí)的問題解決,感興趣的可以了解一下2024-09-09
java實(shí)現(xiàn)上傳文件到服務(wù)器和客戶端
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)上傳文件到服務(wù)器和客戶端,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01

