我們通過瀏覽器訪問不同的路徑,就是在發送不同的請求,在發送請求時,可能會帶一些參數,本文將介紹了Spring MVC中處理不同請求參數的多種方式
一、傳遞單個參數
接收單個參數,在Spring MVC中直接用方法中的參數就可以,如以下代碼:
@RequestMapping("Param")
@RestController
public class ParamController {@RequestMapping("a1")public String tex1(String string){return "接收到參數:"+string;}
}
我們使用Postman傳參后,瀏覽器訪問127.0.0.1:8080/Param/a1?string=Spring
Spring MVC會根據方法,找到對應的參數,賦值給方法,參數不一致,是獲取不到參數,即為null(包裝類型)
注意:
使用基本類型來接收參數時,參數必須傳(除boolean類型),否則報500錯誤;類型不匹配,會報400錯誤(此處400/500等都是狀態碼,其他篇章會涉及講解)
1.1、正常傳遞參數
@RequestMapping("a2")public Object text2(int a){return "接收到參數a:"+a;}
通過Fiddler觀察請求和響應, HTTP響應狀態碼為200(正常)
1.2、不傳a參數
通過Fiddler觀察請求和響應, HTTP響應狀態碼為500(服務器異常)
嘗試觀察程序的錯誤日志,并解決:
可選的整型參數“a”存在,但由于被聲明為基本類型,所以無法轉換為 null 值。建議將其聲明為對應基本類型的對象包裝器。
1.3、傳遞參數類型不匹配
對于包裝類型, 如果不傳對應參數,Spring 接收到的數據則為null。所以開發中,對于參數可能為空的數據,建議使用包裝類型
二、傳遞多個參數
和傳輸一個參數一樣,直接使用方法的參數接收即可
@RestController
public class ParamController {@RequestMapping("Param")public String Demo1(String name,String age){return "接收到參數name: "+name+" ,age: "+age;}
}
使用瀏覽器發送請求并傳參:127.0.0.1:8080/Param?name=小奧奇&age=8
可以發現,后端程序是正確拿到name和age參數的值
當有多個參數時,前后端是以參數的名稱進行參數匹配的,但是參數的位置是不影響后端獲取參數的結果
三、傳遞對象
如果需要傳遞的參數較多時,使用方法傳參就要有很多形參,并且后續每增加一個參數,也要修改方法的聲明,比較麻煩~,在此情況下我們便可以把這些參數封裝成一個對象
Spring MVC 也可以自動實現對象參數的賦值,我們先創建一個Cat對象
public class Cat {private String name;private int age;private String hobby;public String getName() {return name;}public int getAge() {return age;}public String getHobby() {return hobby;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public void setHobby(String hobby) {this.hobby = hobby;}@Overridepublic String toString() {return "Cat{" +"name='" + name + ''' +", age=" + age +", hobby='" + hobby + ''' +'}';}
}
實現傳遞對象的方法
@RequestMapping("Cat")public Object Cat(Cat cat){return cat.toString();}
使用瀏覽器發送請求并傳參:127.0.0.1:8080/Cat?name=咪咪&age=1&hobby=喜歡吃小魚干
正好對應我們Cat類中的三個成員變量,此過程中 Spring 會根據參數名稱自動綁定到對象的各個屬性上,如果屬性未傳遞,則會賦值位null(基本類型會被賦值為默認初始值,比如 int 賦值 0)
四、后端參數重命名(后端參數映射)
在一些情況下,前端傳遞的參數 key 和我們后端接受的 key 可以不一致,比如前端想加密URL中的信息,會使用 p 傳遞給后端,后端是使用 password 字段來接收的(保證可讀性,不然后續維護時,不知道 p 到底是什么),如果出現這種情況,我們可以使用 @RequestParam 來重命名前后端的參數值
@RequestMapping("A1")public String A1(@RequestParam("p") String password){return "接收參數: password:"+password;}
該注解表示從前端接收到 p 賦值給 password
那如果我們直接傳遞給后端的參數 password 呢?
2025-05-30T22:37:36.378+08:00 WARN 27268 — [SpringDemo1] [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter ‘p’ for method parameter type String is not present]
控制臺打印日志顯示:請求參數 p 不存在
那既然是 String 引用類型,我們嘗試不傳參數試試,會不會得到 null ~~
我們發現,當不傳參數時,直接報客戶端錯誤了,因為當我們使用該注解時,這個參數就變成必傳參數了,我們點進該注解的源碼中:
表示:若請求缺失此參數,會拋出**MissingServletRequestParameterException
**,返回 HTTP 400(Bad Request) 錯誤,我們可以通過設置該 required 使該參數為非必傳參數
@RequestMapping("A1")public String A1(@RequestParam(value = "p",required = false) String password){return "接收參數: password:"+password;}
將required 設置為 false ,再次空傳參數得到:
結論:
使用 @RequestParam 進行參數重命名時,請求參數只能和 @RequestParam 聲明的名稱一致,才能進行參數綁定和賦值
使用 @RequestParam 進行參數重命名時, 參數就變成了必傳參數
五、傳遞數組
@RequestMapping("A2")public String A2(String[] arr){return "接收參數:arr:"+ Arrays.toString(arr);}
和傳遞引用類型一樣,直接把數組當成參數,那數組包含多個元素,我們該如何傳遞呢?
此外,我們還可以直接使用方式二在一行中傳遞多個元素:
可以看到,方式二每個元素是以逗號分隔的,但是如果我們本來就要傳遞一個逗號呢?
那么逗號就會轉義為%2c
六、傳遞集合
集合參數:和數組類似,同一個請求中出現多個同名參數,需要使用@RequestParam綁定參數關系,Spring自動將其值收集到一個集合中
@RequestMapping("A1")public String A1(@RequestParam List<Integer> list){return "接收參數:"+list;}
七、傳遞JSON數據
7.1、概念
JSON概念:JSON 全稱為 JavaScript Object Notation(JavaScript 對象表示法),是一種輕量級的數據交互格式。
簡單來說:JSON就是客戶端和服務端進行交互的一種數據格式,有自己的格式和語法,使用文本表示對一個對象或數組的信息,因此本質上是字符串,主要負責在不同的語言中數據傳遞和交換
7.2、JSON語法
還可以壓縮為:
{“name”:“Json.CN”,“url”:“http://www.json.cn”,“page”:88,“isNonProfit”:true,“address”:{“street”:“科技園路.”,“city”:“江蘇蘇州”,“country”:“中國”},“links”:[{“name”:“Google”,“url”:“http://www.google.com”},{“name”:“Baidu”,“url”:“http://www.baidu.com”},{“name”:“SoSo”,“url”:“http://www.SoSo.com”}]}
我們可以使用在線JSON格式化工具來進行校驗和書寫:https://www.bejson.com/
7.3、JSON的優點:
- 簡單易用:語法簡單,易于理解和編寫,可以快速進行數據交換。
- 跨平臺支持:JSON可以被多種編程語言解析和生成,可以在不同的平臺和語言之間進行數據交換和傳輸。
- 輕量級:相較于XML格式,JSON數據格式更加輕量級,傳輸數據時占用帶寬較小,可以提高數據傳輸速度。
- 易于擴展:JSON的數據結構靈活,支持嵌套對象和數組等復雜的數據結構,便于擴展和使用。
- 安全性:JSON數據格式是一種純文本格式,不包含可執行代碼,不會執行惡意代碼,因此具有較高的安全性。
7.4、JSON字符串和Java對象互轉
Spring MVC框架集成了JSON的轉換工具,我們可以直接使用來完成兩者的互轉
本質上是 jackson-databind 提供的功能,SpringMVC框架中已經把該工具包引入了進來,咱們直接使用即可,如果脫離SpringMVC使用,需要引入相關依賴
使用 ObjectMapper 對象提供的兩個方法,可以完成對象和JSON字符串的互轉 writeValueAsString: 把對象轉為JSON字符串 readValue: 把字符串轉為對象
public class JSONText {@Testpublic void JsontoJava() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();//定義一個JSON字符串String s="{"name":"咪咪","age":1,"color":"blue"}";//轉對象Animals cat=mapper.readValue(s,Animals.class);System.out.println(cat.toString());}@Testpublic void JavatoJson() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();//創建Java對象Animals cat = new Animals();cat.setName("cat");cat.setAge(1);cat.setColor("blue");//轉換為JSONString str = mapper.writeValueAsString(cat);System.out.println(str);}
}
7.5、傳遞JSON對象
接收JSON對象,需要使用@RequestBody注解
RequestBody:請求正文,意思是這個注解作用在請求正文的數據綁定,請求參數必須寫在請求正文中。
@RequestMapping("A3")public String A3(@RequestBody Animals animals){return animals.toString();}
我們再postman中傳入的是JSON格式的字符串,但在后端代碼中,Spring會把我們傳入的JSON字符串轉化成一個對象,我們就不用自己轉化為Java對象了,還可以對此對象進行操作:
@RequestMapping("A3")public String A3(@RequestBody Animals animals){System.out.println(animals.getColor());animals.color="彩虹色";return animals.toString();}
八、獲取URL中參數@PathVariable
這個注解主要作用在請求URL路徑上的數據綁定(默認傳遞參數寫在URL上,Spring MVC 就可以獲取到)
@RequestMapping("A4/{id}")public String A4(@PathVariable Integer id){return "獲取id: "+id;}
我們還可以傳遞兩個參數:
@RequestMapping("A4/{id}/{age}")public String A4(@PathVariable Integer id,@PathVariable Integer age) {return "獲取id: "+id+",age: "+age;}
這兩個也默認為必傳參數,如果我們只傳遞一個參數,會發生客戶端錯誤,那么我們是否可以設置為非必傳參數
答案是:理論上可以,但是我們若對改路徑傳一個參數,那么這個參數是id還是age****Spring也不知道,所以參數是必傳的,另外我們可以重命名(此處不再演示)
九、上傳文件@RequestPart
@RequestMapping("A5")public String A5(MultipartFile file) {System.out.println(file.getOriginalFilename());return "文件獲取成功";}