SpringMVC如何正確接收時間的請求示例分析
前言
一般我們對前端提供的http接口為以下三種方式
- GET請求
- POST請求,表單提交
- POST請求,JSON提交
從SpringMVC的處理來看
第一種方式通過@RequestParam或者@PathVariable來接收
第二種方式通過@RequestParam來接收
第三種方式通過@RequestBody來接收
為什么第一二種方式都可以使用@RequestParam來接收參數(shù)??
因為這兩種方式,在sevlet規(guī)范中,都是通過getParameter方法獲取對應(yīng)的參數(shù)
重點! For HTTP servlets, parameters are contained in the query string or posted form data.
對于springmvc,更精確的來講
@RequestParam對應(yīng)RequestParamMethodArgumentResolver處理器
@PathVariable對應(yīng)PathVariableMethodArgumentResolver處理器
@RequestBody對應(yīng)RequestResponseBodyMethodProcessor處理器
這些處理器主要邏輯為,提取參數(shù),轉(zhuǎn)換參數(shù)。
針對@RequestParam和@PathVariable提取到的參數(shù)都是String字符串,因此使用到了Spring的轉(zhuǎn)換服務(wù)
ConversionService進(jìn)行轉(zhuǎn)換,最終調(diào)用到DateFormatter這個類。
對于RequestBody,提取到的參數(shù)也是String字符串,不過這個字符串是Json類型的,因此使用到了HttpMessageConverter。
在SpringBoot中針對Json的轉(zhuǎn)換,默認(rèn)使用了MappingJackson2HttpMessageConverter。
使用
通過@RequestParam接收
GET請求
@GetMapping("/dateFromRequestParam") public String dateFromRequestParam(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date){ return SIMPLE_DATE_FORMAT.format(date); }
測試代碼
curl http://localhost:8080/dateFromRequestParam\?date\=2020-10-10%2010:10:10
POST請求+表單提交
@PostMapping("/dateFromRequestParam") public String dateFromRequestParam2(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date){ return SIMPLE_DATE_FORMAT.format(date); }
測試代碼
curl -X POST http://localhost:8080/dateFromRequestParam -d 'date=2020-10-12 10:10:10'
通過@RequestParam方式接受參數(shù)的時候,這個注解也是可以省略的,如果你要控制一個參數(shù)必傳的話,請加上這個注解
通過@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); }
測試代碼
curl http://localhost:8080/dateFromPathVariable/2020-10-10%2010:10:10
通過@RequestBody接收
POST請求+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"}'
時區(qū)問題
使用Date類型接受時間字符串十分簡單,最麻煩的問題的時差問題。
明明前端給了你10點鐘,為什么變成了18點鐘。
因為上述兩種方式對于時區(qū)的處理是不一樣的,針對@RequestBod,他底層使用了Jackson,因為Jackson默認(rèn)的時區(qū)配置為UTC,也就是0時區(qū)。
因此你通過0時區(qū)接受了時間2020-10-10 10:00:00 , 而在保存數(shù)據(jù)庫,或者你輸出的時候,使用的都是我們當(dāng)前機(jī)器所在的時區(qū),也就是東8區(qū),因此會加8個小時。
因此針對jackson框架,我們需要指定為東八區(qū),
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
而對于@RequestParam這種由spring內(nèi)置轉(zhuǎn)換器處理的時間,底層使用的是SimpleDateFormat,默認(rèn)使用的操作系統(tǒng)的時區(qū),所以我們無需對時區(qū)進(jìn)行配置。
@DateTimeFormat的錯誤使用
在我們的業(yè)務(wù)代碼中,我發(fā)現(xiàn)了一些以下的錯誤代碼
比如
@Data public static class Input{ @DateTimeFormat(pattern = "yyyy-MM-dd") private Date date; }
用它來接收前端傳過來的{"date":"2020:10:10"}
拜托,@DateTimeFormat是spring的注解,針對Jackson根本不會失效。
只因為Jackson默認(rèn)的反序列化支持2種格式的時間字符串,yyyy-MM-dd
和yyyy-MM-dd'T'HH:mm:ss.SSSZ
并且時區(qū)上也是存在問題的。
只不過因為剛好你的業(yè)務(wù)代碼是忽略后面的Time,你才逃過一劫。
參考 http://www.dbjr.com.cn/program/285772dl4.htm
以上就是SpringMVC如何正確接收時間示例分析的詳細(xì)內(nèi)容,更多關(guān)于SpringMVC接收時間的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java中BeanUtils.copyProperties的11個坑總結(jié)
我們?nèi)粘i_發(fā)中,經(jīng)常涉及到DO、DTO、VO對象屬性拷貝賦值,很容易想到org.springframework.beans.BeanUtils的copyProperties,它會自動通過反射機(jī)制獲取源對象和目標(biāo)對象的屬性,pyProperties,會有好幾個坑呢,本文將給大家總結(jié)一下遇到的坑,需要的朋友可以參考下2023-05-05Eclipse中使用Maven創(chuàng)建Java Web工程的實現(xiàn)方式
這篇文章主要介紹了Eclipse中使用Maven創(chuàng)建Java Web工程的實現(xiàn)方式的相關(guān)資料,希望通過本文能幫助到大家,讓大家實現(xiàn)這樣的方式,需要的朋友可以參考下2017-10-10詳解springmvc控制登錄用戶session失效后跳轉(zhuǎn)登錄頁面
本篇文章主要介紹了springmvc控制登錄用戶session失效后跳轉(zhuǎn)登錄頁面,session一旦失效就需要重新登陸,有興趣的同學(xué)可以了解一下。2017-01-01