SpringMVC如何正確接收時(shí)間的請(qǐng)求示例分析
前言
一般我們對(duì)前端提供的http接口為以下三種方式
- GET請(qǐng)求
- POST請(qǐng)求,表單提交
- POST請(qǐng)求,JSON提交
從SpringMVC的處理來(lái)看
第一種方式通過(guò)@RequestParam或者@PathVariable來(lái)接收
第二種方式通過(guò)@RequestParam來(lái)接收
第三種方式通過(guò)@RequestBody來(lái)接收
為什么第一二種方式都可以使用@RequestParam來(lái)接收參數(shù)??
因?yàn)檫@兩種方式,在sevlet規(guī)范中,都是通過(guò)getParameter方法獲取對(duì)應(yīng)的參數(shù)

重點(diǎn)! For HTTP servlets, parameters are contained in the query string or posted form data.
對(duì)于springmvc,更精確的來(lái)講
@RequestParam對(duì)應(yīng)RequestParamMethodArgumentResolver處理器
@PathVariable對(duì)應(yīng)PathVariableMethodArgumentResolver處理器
@RequestBody對(duì)應(yīng)RequestResponseBodyMethodProcessor處理器
這些處理器主要邏輯為,提取參數(shù),轉(zhuǎn)換參數(shù)。
針對(duì)@RequestParam和@PathVariable提取到的參數(shù)都是String字符串,因此使用到了Spring的轉(zhuǎn)換服務(wù)
ConversionService進(jìn)行轉(zhuǎn)換,最終調(diào)用到DateFormatter這個(gè)類。
對(duì)于RequestBody,提取到的參數(shù)也是String字符串,不過(guò)這個(gè)字符串是Json類型的,因此使用到了HttpMessageConverter。
在SpringBoot中針對(duì)Json的轉(zhuǎn)換,默認(rèn)使用了MappingJackson2HttpMessageConverter。
使用
通過(guò)@RequestParam接收
GET請(qǐng)求
@GetMapping("/dateFromRequestParam")
public String dateFromRequestParam(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date){
return SIMPLE_DATE_FORMAT.format(date);
}
測(cè)試代碼
curl http://localhost:8080/dateFromRequestParam\?date\=2020-10-10%2010:10:10
POST請(qǐng)求+表單提交
@PostMapping("/dateFromRequestParam")
public String dateFromRequestParam2(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date){
return SIMPLE_DATE_FORMAT.format(date);
}
測(cè)試代碼
curl -X POST http://localhost:8080/dateFromRequestParam -d 'date=2020-10-12 10:10:10'
通過(guò)@RequestParam方式接受參數(shù)的時(shí)候,這個(gè)注解也是可以省略的,如果你要控制一個(gè)參數(shù)必傳的話,請(qǐng)加上這個(gè)注解
通過(guò)@PathVariable接受
@GetMapping("/dateFromPathVariable/{date}")
public String dateFromPathVariable(@PathVariable("date") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date){
return SIMPLE_DATE_FORMAT.format(date);
}
測(cè)試代碼
curl http://localhost:8080/dateFromPathVariable/2020-10-10%2010:10:10
通過(guò)@RequestBody接收
POST請(qǐng)求+JSON提交
@PostMapping("/dateFromJson")
public String dateFromJson(@RequestBody Input param){
return SIMPLE_DATE_FORMAT.format(param.getDate());
}
@Data
public static class Input{
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date date;
}代碼
curl -X POST -H 'Content-Type: application/json' http://localhost:8080/dateFromJson -d '{"date":"2020-10-12 10:10:10"}'時(shí)區(qū)問(wèn)題
使用Date類型接受時(shí)間字符串十分簡(jiǎn)單,最麻煩的問(wèn)題的時(shí)差問(wèn)題。
明明前端給了你10點(diǎn)鐘,為什么變成了18點(diǎn)鐘。
因?yàn)樯鲜鰞煞N方式對(duì)于時(shí)區(qū)的處理是不一樣的,針對(duì)@RequestBod,他底層使用了Jackson,因?yàn)镴ackson默認(rèn)的時(shí)區(qū)配置為UTC,也就是0時(shí)區(qū)。

因此你通過(guò)0時(shí)區(qū)接受了時(shí)間2020-10-10 10:00:00 , 而在保存數(shù)據(jù)庫(kù),或者你輸出的時(shí)候,使用的都是我們當(dāng)前機(jī)器所在的時(shí)區(qū),也就是東8區(qū),因此會(huì)加8個(gè)小時(shí)。
因此針對(duì)jackson框架,我們需要指定為東八區(qū),
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
而對(duì)于@RequestParam這種由spring內(nèi)置轉(zhuǎn)換器處理的時(shí)間,底層使用的是SimpleDateFormat,默認(rèn)使用的操作系統(tǒng)的時(shí)區(qū),所以我們無(wú)需對(duì)時(shí)區(qū)進(jìn)行配置。
@DateTimeFormat的錯(cuò)誤使用
在我們的業(yè)務(wù)代碼中,我發(fā)現(xiàn)了一些以下的錯(cuò)誤代碼
比如
@Data
public static class Input{
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date date;
}
用它來(lái)接收前端傳過(guò)來(lái)的{"date":"2020:10:10"}
拜托,@DateTimeFormat是spring的注解,針對(duì)Jackson根本不會(huì)失效。
只因?yàn)镴ackson默認(rèn)的反序列化支持2種格式的時(shí)間字符串,yyyy-MM-dd和yyyy-MM-dd'T'HH:mm:ss.SSSZ
并且時(shí)區(qū)上也是存在問(wèn)題的。
只不過(guò)因?yàn)閯偤媚愕臉I(yè)務(wù)代碼是忽略后面的Time,你才逃過(guò)一劫。
參考 http://www.dbjr.com.cn/program/285772dl4.htm
以上就是SpringMVC如何正確接收時(shí)間示例分析的詳細(xì)內(nèi)容,更多關(guān)于SpringMVC接收時(shí)間的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java中BeanUtils.copyProperties的11個(gè)坑總結(jié)
我們?nèi)粘i_(kāi)發(fā)中,經(jīng)常涉及到DO、DTO、VO對(duì)象屬性拷貝賦值,很容易想到org.springframework.beans.BeanUtils的copyProperties,它會(huì)自動(dòng)通過(guò)反射機(jī)制獲取源對(duì)象和目標(biāo)對(duì)象的屬性,pyProperties,會(huì)有好幾個(gè)坑呢,本文將給大家總結(jié)一下遇到的坑,需要的朋友可以參考下2023-05-05
淺談springMVC攔截器和過(guò)濾器總結(jié)
本篇文章主要介紹了springMVC攔截器和過(guò)濾器總結(jié),可以用來(lái)對(duì)訪問(wèn)的url進(jìn)行攔截處理,有興趣的可以了解一下。2017-01-01
Eclipse中使用Maven創(chuàng)建Java Web工程的實(shí)現(xiàn)方式
這篇文章主要介紹了Eclipse中使用Maven創(chuàng)建Java Web工程的實(shí)現(xiàn)方式的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家實(shí)現(xiàn)這樣的方式,需要的朋友可以參考下2017-10-10
詳解springmvc控制登錄用戶session失效后跳轉(zhuǎn)登錄頁(yè)面
本篇文章主要介紹了springmvc控制登錄用戶session失效后跳轉(zhuǎn)登錄頁(yè)面,session一旦失效就需要重新登陸,有興趣的同學(xué)可以了解一下。2017-01-01

