解讀SpringMVC?請求參數接收
在瀏覽器與程序進行交互時,主要分為三個階段:
1. 建立連接:將用戶(瀏覽器)和 Java 程序連接起來,也就是訪問一個地址能夠調用到 Spring程序
2. 請求:用戶請求時會攜帶一些參數,在程序中要想辦法獲取到參數,因此請求這部分主要是獲取參數的功能
3. 響應:在執(zhí)行了業(yè)務邏輯之后,要將程序執(zhí)行的結果返回給客戶,也就是響應
在本篇文章中,我們來學習請求(獲取參數 )這部分內容
請求
訪問不同的路徑,就是發(fā)送不同的請求,在發(fā)送請求時,可能會帶一些參數,因此學習 Spring 的請求,主要就是學習 如何傳遞參數到后端 以及 后端如何接收參數
在本篇文章中,為了更方便學習,則不采用前端傳遞參數,而是使用 瀏覽器 和 postman 來模擬
傳遞單個參數
接收單個參數時,直接用方法中的參數即可:
@RequestMapping("/user")
@RestController
public class UserController {
@RequestMapping(value = "/login")
public String login(String name) {
return "接收到用戶名: " + name;
}
}使用 瀏覽器發(fā)送請求:127.0.0.1:8080/user/login?name=zhangsan

后端程序正確拿到 name 參數的值
Spring MVC 會根據方法的參數名,找到對應的參數,賦值給方法

當參數名稱不一致時,獲取不到參數:

當未傳遞參數時:

基本類型參數傳遞
我們測試使用基本類型來接收參數時:
@RequestMapping("/test")
@RestController
public class TestController {
@RequestMapping("/getInt")
public String getInt(int age) {
return "接收到參數age: " + age;
}
}
未傳遞參數

報了 500 錯誤
500 錯誤碼是指"Internal Server Error"(服務器內部錯誤),是表示服務器在處理請求時遇到了未知的錯誤或異常情況。這種錯誤通常是由服務器端代碼出現問題引起的,而不是客戶端請求的問題。
我們查看日志信息:

int 類型的參數 age 雖然是可選的,但是由于被聲明為基本類型而不能轉換為空值。考慮將其聲明為對應基本類型的包裝類型
我們使用包裝類型 Integer 來接收參數:
@RequestMapping("/getInteger")
public String getInt(Integer age) {
return "接收到參數age: " + age;
}
當未傳遞對應參數時,接收到的數據為 null
在使用基本類型來接收參數時,參數必須傳(除了 boolean 類型)
當使用 boolean 類型接收時:
@RequestMapping("/getBoolean")
public String getBoolean(boolean b) {
return "接收到參數b: " + b;
}未傳遞參數時,默認值為 false:

因此,對于參數可能為空的數據,建議使用包裝類型接收
傳遞參數類型不匹配

此時報了 400 錯誤
400 錯誤碼是指"Bad Request"(錯誤請求),表示服務器無法理解客戶端發(fā)送的請求,因為請求語法有誤、請求參數無效或者請求消息體格式錯誤等。
我們觀察后端日志:

類型轉換失敗
傳遞多個參數
與接收單個參數一樣,直接使用方法的參數接收即可:
@RequestMapping(value = "/login")
public String login(String name, String password) {
return "接收到用戶名: " + name + " 接收到密碼: " + password;
}
后端程序正確拿到了 name 和 password 參數的值
當有多個參數時,前后端進行參數匹配時,是以參數的名稱進行匹配的,因此參數的位置不影響后端數據獲取參數的結果

傳遞對象
當參數比較多時,就需要很多形參,并且每增加一個參數,就需要修改方法的聲明,此時,我們可以將這些參數封裝為一個對象
public class Student {
private int id;
private String name;
private int age;
private String sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}傳遞對象:
@RequestMapping("/getStudent")
public String getStudent(Student student) {
return "接收到參數student: " + student;
}后端程序正確接收到各個屬性的值

Spring 會根據參數名稱自動綁定到對象的各個屬性

當某個屬性未傳遞時,則賦值為null,基本類型則賦值為默認初始值

后端參數重命名
前端傳遞的參數 key 和 后端接收到的 key 可以不一致,例如前端傳遞參數 name 給后端,而后端使用 userName 來接收,這種請求下,我們可以使用注解 @RequestParam 來重命名前后端的參數值
@RequestMapping("/user")
@RestController
public class UserController {
@RequestMapping("/login")
public String login(@RequestParam("name") String userName) {
return "接收到用戶名: " + userName;
}
}
傳遞的參數 name 正確綁定到后端參數 userName 上

而此時,若使用 userName 進行傳參:

觀察打印的錯誤日志:

請求參數 name 不存在
我們可以發(fā)現:
1. 在使用 @RequestParam 進行重命名時,請求參數只能與 @RequestParam 聲明的名稱一致,才能進行參數綁定和賦值
2. 在使用 @RequestParam 進行重命名時,參數就變成了必傳參數
在使用 @RequestParam 時,若前端參數是一個非必傳參數,此時該如何解決呢?
我們查看 @RequestParam 注解的實現細節(jié):

我們可以看到, required 的默認值為 true,表示:該注解修飾的參數默認為必傳
因此,我們可以設置 @RequestParam 中的 required = false,來避免不傳遞參數時報錯:
@RequestMapping("/login")
public String login(@RequestParam(value = "name", required = false) String userName) {
return "接收到用戶名: " + userName;
}在添加 required = false后,name 前面也加上了 key,value = "name"
注解屬性賦值時,若未指明 key,則默認為 value 屬性
若需要有多個屬性進行賦值,則需要寫上 key
傳遞數組
Spring MVC 可以自動綁定數組參數的賦值:
@RequestMapping("/test")
@RestController
public class TestController {
@RequestMapping("getArray")
public String getArray(String[] array) {
return Arrays.toString(array);
}
}發(fā)送請求并傳參:

中間分割的 , 必須為英文的逗號
也可使用:

請求參數名與形參數組名稱相同且請求參數多個,后端定義數組類型形參即可接收參數
傳遞集合
集合參數與數組類似,同一個請求參數名有多個,且需要使用 @RequestParam 綁定參數關系
默認情況下,請求中參數名相同的多個值,是封裝到數組中的,若需要封裝到集合中,需要使用 @RequestParam 綁定參數關系
@RequestMapping("/getList")
public String getList(@RequestParam List<String> list) {
return "接收到參數list" + list;
}同樣的,有兩種方式進行傳參:


傳遞JSON數據
JSON是什么
JSON(JavaScript Object Notation)是一種輕量級的數據交換格式,易于人類閱讀和編寫,也易于機器解析和生成。其就是一種數據格式,有自己的格式和語法,使用文本表示一個對象或數組的信息,因此 JSON本質是字符串,主要負責在不同的語言中數據傳遞和交互
我們來看一段JSON數據:
{
"name": "zhangsan",
"age": 18,
"isStudent": true,
"courses": ["Math", "English", "History"]
}也可以壓縮表示:
{"name":"zhangsan","age":18,"isStudent":true,"courses":["Math","English","History"]}與上面描述的數據是一樣的,只是上面的進行了格式化,更易讀
JSON的語法:
數據在 鍵值對(key/value)中
數據由逗號, 分割
對象用{}表示
數組用[]表示
值可以為對象,也可以為數組,數組中可以包含多個對象
JSON中的兩種結構:
對象:{} 保存的對象是一個 無序的鍵值對集合, 一個對象以 { 開始,} 結束,每個鍵(key)后面跟一個 : ,鍵值對使用 , 分割
數組:[]保存的數組是值(value)的有序集合,一個數組以 [ 開始,] 結束,值之間使用 , 分割
在使用JSON時,我們可以使用在線JSON格式化工具進行校驗和書寫
JSON 字符串和Java對象互轉
JSON 本質上是一個字符串,通過文本來存儲和描述數據
Spring MVC 框架也集成了 JSON 的轉換工具,我們可以直接使用,來完成 JSON 字符串和 Java對象的互轉
本質是是 jackson-databind 提供的功能,Spring MVC 框架中已經將該工具包引進了,直接使用即可,若脫離 Spring MVC 使用,需要引入相關依賴
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.5</version> </dependency>
JSON的轉換工具包有很多,也可以使用其他的
@SpringBootTest
class JSONUtilsTest {
@Autowired
private ObjectMapper objectMapper;
@Test
public void jsonTest() throws JsonProcessingException {
Student student = new Student();
student.setId(1);
student.setName("zhangsan");
student.setAge(13);
student.setSex("男");
// 將對象轉換為 JSON 字符串
String jsonStr = objectMapper.writeValueAsString(student);
System.out.println("JSON字符串為:" + jsonStr);
// 將JSON字符串轉換為對象
Student student1 = objectMapper.readValue(jsonStr, Student.class);
System.out.println("轉換的對象:" + student1);
}
}使用 ObjectMapper 對象提供的兩個方法,可以完成 對象 和 JSON 字符串的互換
writeValueAsString:將對象轉換為JSON字符串
readValue:將字符串轉換為對象
運行結果:

JSON的優(yōu)點
1. 易于理解和閱讀: JSON采用了人類可讀的文本格式,基本上可以直接閱讀和理解,這使得開發(fā)人員和數據工程師可以輕松地查看數據內容。
2. 輕量和高效: JSON數據以文本形式存儲,相比于其他二進制格式如XML,它的數據量通常更小,傳輸和解析速度更快,特別是在網絡傳輸和移動設備上更為高效。
3. 跨平臺和語言無關: JSON在多種編程語言中都有支持和解析庫,因此可以在不同的平臺和系統中使用和傳輸數據,無需擔心兼容性問題。
4. 易于解析和生成: JSON數據格式簡單明了,解析起來也比較容易。幾乎所有現代編程語言都有JSON解析器和生成器,可以方便地將JSON數據轉換成各種數據結構或者將數據結構轉換成JSON格式
5. 安全性較高:JSON數據格式是一種純文本格式,不包含可執(zhí)行代碼,不會執(zhí)行惡意代碼,因此具有較高的安全性
因此,JSON在web應用程序中被廣泛使用(前后端數據交互、API接口數據傳輸等等)
傳遞JSON對象
接收JSON對象,需要使用 @RequestBody 注解
@RequestBody:RequestBody,即請求正文,表示這個注解作用在請求正文的數據綁定,請求參數必須寫在請求正文中,@RequestBody 注解的作用是將HTTP請求體中的數據轉換為Java對象,并作為方法的參數傳入
@RequestMapping("/getStudent")
public String getStudent(@RequestBody Student student) {
return "接收到參數student: " + student;
}使用postman發(fā)送JSON請求參數:

后端成功接收
獲取URL中的參數
在獲取URL中的參數時,我們需要使用 @PathVariable 注解
@RequestMapping("/user")
@RestController
public class UserController {
@RequestMapping("/login/{id}/{name}")
public String login(@PathVariable Integer id, @PathVariable String name) {
return "接收到id: " + id + " 接收到name: " + name;
}
}使用postman測試:

后端正確獲取到URL中的參數
當方法的參數名稱和需要綁定的URL中的變量名稱一致時,可以不用給 @PathVariable 的屬性賦值
而當方法的參數名稱和需要綁定的URL中的變量名稱不一致時,需要對 @PathVariable的屬性value賦值
@RequestMapping("/login/{id}/{name}")
public String login(@PathVariable Integer id, @PathVariable("name") String userName) {
return "接收到id: " + id + " 接收到name: " + userName;
}
文件上傳
在傳輸文件時,我們需要使用 @RequestPart
@RequestMapping("/test")
@RestController
public class TestController {
@RequestMapping("getFile")
public String getFile(@RequestPart("file")MultipartFile multipartFile) throws IOException {
// 獲取文件名
String fileName = multipartFile.getOriginalFilename();
// 將文件上傳到指定路徑
multipartFile.transferTo(new File("D:/" + multipartFile.getOriginalFilename()));
return "接收到文件:" + fileName;
}
}使用postman發(fā)送請求:

同時查看文件是否上傳成功:

到此這篇關于SpringMVC 請求參數接收的文章就介紹到這了,更多相關SpringMVC 請求參數接收內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
springboot?集成identityserver4身份驗證的過程解析
這篇文章主要介紹了springboot?集成identityserver4身份驗證的相關知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01
淺析Java迭代器Iterator和Iterable的區(qū)別
Java語言中,Iterator和Iterable都是用來遍歷集合類數據結構的接口,雖然它們有很多相似的地方,但在具體實現中卻有著一些不同之處,本文將詳細分析它們的區(qū)別,并提供相應的代碼示例,需要的朋友可以參考下2023-07-07

