SpringMVC前后端參數(shù)映射
在web開發(fā)中我們都要進(jìn)行前端傳參后端取參的過程,今天就簡單記錄下針對GET, POST, PUT, DELETE 請求的參數(shù)該如何映射。
1. GET 請求的參數(shù)映射
1.1 參數(shù)名映射
GET請求是最簡單的,只需要將參數(shù)以鍵值對的形式拼接到url后面就可以了,比如下面:
http://localhost:8080/helloParam?name=zhangsan&age=33\n &birthDay=2023-08-01 20:01:11\n &plays=basketabll&plays=football&plays=swimming
后端可以去獲取參數(shù):
@GetMapping(value = "/helloParam") public String hello(String name, Integer age, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime birthDay, String[] plays, @RequestParam("plays") List<String> plays2) { log.info("請求參數(shù): name = {}, age = {}, birthDay = {}, plays = {}, plays2 = {}", name, age, birthDay, plays, plays2); return "success"; } //日志輸出:請求參數(shù): name = zhangsan, age = 33, birthDay = 2023-08-01T20:01:11, plays = [basketabll, football, swimming], plays2 = [basketabll, football, swimming]
日期字符串如何想直接映射成 LocalDateTime
類型,需要使用 @DateTimeFormat
注解進(jìn)行標(biāo)注。 plays
是一個數(shù)組,后端可以用數(shù)組或者集合接收,注意用集合接收時,需要搭配 @RequestParam
注解,否則將無法映射成功。
注意:前端的參數(shù)名必須和后端方法的變量名保持一致,如果不一致,將無法映射。如果就不一致,可以使用 @RequestParam
來完成映射。
1.2使用 @RequestParam 注解完成映射
比如:將上面請求參數(shù)中的 name
參數(shù)改為 cname
發(fā)送請求:
http://localhost:8080/helloParam?cname=zhangsan3333&age=33\n &birthDay=2023-08-01 20:01:11\n &plays=basketabll&plays=football&plays=swimming
后端映射:
@GetMapping(value = "/helloParam") public String hello(@RequestParam("cname") String n, Integer age, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime birthDay, String[] plays, @RequestParam("plays") List<String> plays2) { log.info("請求參數(shù): name = {}, age = {}, birthDay = {}, plays = {}, plays2 = {}", n, age, birthDay, plays, plays2); return "success"; } //日志輸出:請求參數(shù): name = zhangsan333, age = 33, birthDay = 2023-08-01T20:01:11, plays = [basketabll, football, swimming], plays2 = [basketabll, football, swimming]
使用 @RequestParam
注解時,要求參數(shù)必須存在,否則請求將會報(bào)錯??梢允褂盟?required
屬性來避免這個問題。
1.3 后端用對象接收參數(shù)
還是上面的請求,比如我需要傳遞分頁參數(shù),而后端的分頁參數(shù)保存在 Page
對象中
http://localhost:8080/helloParam?name=zhangsan3333&age=33\n &birthDay=2023-08-01 20:01:11\n &plays=basketabll&plays=football&plays=swimming\n &page=1&size=10
后端可以這樣接收:
@GetMapping(value = "/helloParam") public String hello(Page page, String name, Integer age, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime birthDay) { log.info("請求參數(shù): name = {}, age = {}, birthDay = {}, 分頁參數(shù):page = {}", n, age, birthDay, page); return "success"; } //日志輸出:請求參數(shù): name = zhangsan3333, age = 33, birthDay = 2023-08-01T20:01:11, 分頁參數(shù):page = Page(page=1, size=10)
Page對象:
@Data public class Page { private Integer page; private Integer size; }
將請求參數(shù)也封裝到對象中:
@GetMapping(value = "/helloParam") public String hello(Page page, Student student) { log.info("請求對象參數(shù): student = {}, 分頁參數(shù) = {}", student, page); return "success"; } //日志輸出:請求對象參數(shù): student = Student(name=zhangsan3333, age=33, birthDay=2023-08-01T20:01:11, plays=[basketabll, football, swimming]), 分頁參數(shù) = Page(page=1, size=10) @Data public class Student { private String name; private Integer age; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime birthDay; private List<String> plays; }
1.4 Restful 風(fēng)格的參數(shù)映射
http://localhost:8080/helloParam/liubei/45/1949-10-01 23:23:44
后端可以這樣接收:
@GetMapping(value = "/helloParam/{cname}/{age}/{birthDay}") public String helloObj2(@PathVariable("cname") String name, Integer age, Student student) { log.info("Restful請求參數(shù): name = {}, age = {}, 對象student = {}", name, age, student); return "success"; } //日志輸出:Restful請求參數(shù): name = liubei, age = null, 對象student = Student(name=null, age=45, birthDay=1949-10-01T23:23:44, plays=null)
@GetMapping("/hello/{name}/{age}/{birthDay}")
這里的{參數(shù)名}要和方法中的參數(shù)名保持一致。而且當(dāng)用單個參數(shù)去接收時,必須搭配 @PathVariable
注解才可以映射成功,否則將無法映射,比如age就無法映射。當(dāng)用對象去接收時,無需指定 @PathVariable
注解,但是對象的屬性名要和Restful的請求{參數(shù)名}保持一致才可以映射成功, Student
類中是 name
,而Rfestul中的請求參數(shù)是 cname
, 所以無法映射。
2. POST 請求的參數(shù)映射
說起 POST
請求,我們先看下幾個比較常見的 Content-Type
。
Content-Type | Content-Type 描述 |
---|---|
multipart/form-data | multipart/form-data就是我們常見的表單,它會將表單的數(shù)據(jù)處理為一條消息,以標(biāo)簽為單元,用分隔符分開。既可以上傳鍵值對,也可以上傳文件(可以多個文件) |
x-www-form-urlencoded | x-www-from-urlencoded,會將表單內(nèi)的數(shù)據(jù)轉(zhuǎn)換為鍵值對,比如,name=zhangsan&age=23,相比multipart/form-data ,它只能上傳鍵值對,不能上傳文件 |
raw | 可以上傳任意格式的文本,比如我們常見的 JOSN( application/json ), 還有其他的 text, xml, html... |
binary | 就是application/octet-stream,只可以上傳二進(jìn)制數(shù)據(jù),通常用來上傳文件或者音頻,沒有鍵值對,一次只能上傳一個文件 |
2.1 Content-Type: application/x-www-form-urlencoded 的參數(shù)映射
multipart/form-data
相比 application/x-www-form-urlencoded
多了文件上傳的功能,其他基本上都是一樣的,所以我就以 application/x-www-form-urlencoded
進(jìn)行演示說明。
2.1.1 參數(shù)名映射
Controller:
@PostMapping(value = "/form") public String form(String name, Integer age, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime birthDay) { log.info("請求參數(shù): name = {}, age = {}, time = {}", name, age, birthDay); return "success"; } //日志輸出:請求參數(shù): name = zhangsan, age = 23, time = 2023-07-31T23:51:23
注意:這里如果要映射成功,確保請求參數(shù)名與方法參數(shù)名稱保持一致。如果不一致,可以使用 @RequestParam
注解來指定.
Controller:
@PostMapping(value = "/form") public String form(@RequestParam("cname") String name, Integer age) { log.info("請求參數(shù): name = {}, age = {}", name, age); return "success"; } //日志輸出:請求參數(shù): name = zhangsan, age = 23
有沒有發(fā)現(xiàn),其實(shí)和GET請求映射一模一樣。
2.1.2 對象映射
@Data public class Student { private String name; private Integer age; private String fromCity; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime birthDay; }
前端沒有變化,還是之前的請求:
curl --location --request POST 'http://localhost:8080/form' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'name=zhangsan' \ --data-urlencode 'age=23' \ --data-urlencode 'birthDay=2023-07-31 23:51:23'
后端用對象接收:
@PostMapping(value = "/form") public String form(Student student) { log.info("obj請求參數(shù): name = {}, age = {}", student.getName(), student.getAge()); return "success"; } //日志輸出:obj請求參數(shù): name = zhangsan, age = 23, time = 2023-07-31T23:51:23
2.2.3 Restful 風(fēng)格的參數(shù)映射
調(diào)整一下請求格式:
curl --location --request POST 'http://localhost:8080/form/zhangxinyu/33'
后端接收:
@PostMapping(value = "/form/{cname}/{age}") public String form(@PathVariable("cname") String name, @PathVariable Integer age, Student student) { log.info("restful請求參數(shù): name = {}, age = {}, student對象 = {}", name, age, student); return "success"; } //日志輸出:obj請求參數(shù): name = zhangxinyu, age = 33, student對象 = Student(name=null, age=33, birthDay=null, plays=null)
@PostMapping(value = "/form/{cname}/{age}")
這里的{參數(shù)名}要和方法中的參數(shù)名保持一致。而且當(dāng)用單個參數(shù)去接收時,必須搭配 @PathVariable
注解才可以映射成功,否則將無法映射。當(dāng)用對象去接收時,無需指定 @PathVariable
注解,但是對象的屬性名要和Restful的請求{參數(shù)名}保持一致才可以映射成功, Student
類中是 name
,而Rfestul中的請求參數(shù)是 cname
, 所以無法映射。和 GET
請求是一樣的。
2.2 Content-Type: application/json 的參數(shù)映射
想要接收 application/json
的數(shù)據(jù),后端的方法參數(shù)上必須標(biāo)注 @RequestBody
注解
2.2.1 @RequestBody
注解完成參數(shù)映射
我們看下后端的接收:
@PostMapping("/application") public String hello(Integer age, @RequestBody String name, LocalDateTime birthDay){ log.info("請求參數(shù): name = {}, age = {}, birthDay = {}", name, age, birthDay); return "success"; }
只有 name
參數(shù)映射上了,這是因?yàn)樗鼤颜麄€body里面的內(nèi)容映射給標(biāo)注了 @RequestBody
參數(shù),而 age
, birthDay
因?yàn)闆]有標(biāo)注 @RequestBody
注解所以無法映射,而且也不能再標(biāo)注 @RequestBody
注解,因?yàn)橹荒芙o一個參數(shù)標(biāo)注,如果多個參數(shù)標(biāo)注 @RequestBody
注解會報(bào)錯。
那如果想給多個參數(shù)都映射成功,怎么處理?可以用 自定義對象
去接收或者 Map
.
自定義 Student
對象去接收:
@Data public class Student { private String name; private Integer age; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") //要用這個注解 //@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") //GET/form 用這個去映射 private LocalDateTime birthDay; private List<String> plays; private Course course; } @Data public class Course { private String id; private String courseName; }
Controller:
@PostMapping("/application") public String hello(@RequestBody Student student){ log.info("請求參數(shù): student對象:{}", student); return "success" + student.getBirthDay(); } //日志輸出:請求參數(shù): student對象:Student(name=周星馳, age=50, birthDay=2023-08-02T20:36:04, plays=null, course=null)
2.2.2 使用 @JsonProperty
注解映射參數(shù)名不一致的情況
javaBean對象:
@Data public class Student { //使用JsonProperty("username")注解完成映射 @JsonProperty("username") private String name; private Integer age; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") //@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime birthDay; private List<String> plays; private Course course; }
2.2.3 使用 @JsonIgnore
注解忽略不需要映射的字段
如果前端不需要展示某個字段,也可以用這個注解標(biāo)注
JavaBean對象:
@Data public class Student { @JsonProperty("username") private String name; @JsonIgnore private Integer age; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") //@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime birthDay; private List<String> plays; @JsonIgnore private Course course; }
Controller:
@Slf4j @RestController public class HelloController { @PostMapping("/application") public Student hello(@RequestBody Student student){ log.info("請求參數(shù): student對象:{}", student); return student; } } //日志輸出:請求參數(shù): student對象:Student(name=周星馳, age=null, birthDay=2023-08-02T20:36:04, plays=[swimming, singing], course=null)
看下返回給前端的JSON數(shù)據(jù):
像 age
, course
這種標(biāo)注了 @JsonIgnore
注解的屬性就不會顯示在JSON中了。
到此這篇關(guān)于SpringMVC前后端參數(shù)映射的文章就介紹到這了,更多相關(guān)SpringMVC參數(shù)映射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Volatile應(yīng)用單例模式實(shí)現(xiàn)過程解析
這篇文章主要介紹了Java Volatile應(yīng)用單例模式實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11IntelliJ IDEA maven 構(gòu)建簡單springmvc項(xiàng)目(圖文教程)
在工作當(dāng)中,我們有時需要創(chuàng)建一個全新的工程,而基于spring-mvc web的工程較為常見,這篇文章主要介紹了IntelliJ IDEA maven 構(gòu)建簡單springmvc項(xiàng)目(圖文教程),感興趣的小伙伴們可以參考一下2018-05-05Java集合基礎(chǔ)知識 List/Set/Map詳解
這篇文章主要介紹了Java集合基礎(chǔ)知識 List/Set/Map,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03Java中字符串轉(zhuǎn)int數(shù)據(jù)類型的三種方式
這篇文章主要介紹了Java中字符串轉(zhuǎn)int數(shù)據(jù)類型的三種方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03