最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring MVC 請求參數(shù)處理全解析

 更新時間:2025年12月22日 10:30:12   作者:Han.miracle  
本文主要介紹了Spring框架中處理HTTP請求參數(shù)的方法,包括傳遞單個參數(shù)、多個參數(shù)、對象參數(shù)、數(shù)組、集合、JSON數(shù)據(jù)、路徑變量、上傳文件、Cookie和Session的獲取以及Header的獲取,感興趣的朋友一起看看吧

2.4 請求

訪問不同的路徑,就是發(fā)送不同的請求。在發(fā)送請求時,可能會帶一些參數(shù),所以學習 Spring 的請求,主要是學習如何傳遞參數(shù)到后端以及后端如何接收.傳遞參數(shù),咱們主要是使用瀏覽器和 Postman 來模擬

后端開發(fā)人員無需過度關注如何傳遞參數(shù),了解即可,實際開發(fā)中以 Postman 測試為主.比如餐廳的廚師,不關注用戶是在店里下單,還是外賣平臺下單,或者小程序下單,只需要知道如何接收訂單,根據(jù)訂單做出對應的菜肴就可以了.

2.4.1 傳遞單個參數(shù)

接收單個參數(shù),在 Spring MVC 中直接用方法中的參數(shù)就可以,比如以下代碼:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/param")
public class ParamController {
    @RequestMapping("m1")
    public String method1(String name){
        return "接收到參數(shù)name:"+ name;
    }
}

咱們使用瀏覽器發(fā)送請求并傳參http://127.0.0.1:8080/param/m1?name=spring

可以看到,后端程序正確拿到了name參數(shù)的值

 Spring MVC會根據(jù)方法的參數(shù)名,找到對應的參數(shù),賦值給方法

如果參數(shù)不?致,是獲取不到參數(shù)的.

比如請求URL:http://127.0.0.1:8080/param/m1?name1=spring 響應結果

那Postman中測試的結果

注意事項 :

使用基本類型來接收參數(shù)時,參數(shù)必須傳(除boolean類型),否則會報500錯誤

類型不匹配時,會報400錯誤.

特殊情況:

1.不傳參數(shù):報了一個500的狀態(tài)碼,我們看后端日志

通過Fiddler觀察請求和響應,HTTP響應狀態(tài)碼為500

?般看日志堆棧信息的首行,報錯信息顯示: int類型的參數(shù)'age',雖然為可選的,但由于被聲明為基本類型而不能轉換為空值.考慮將其聲明為對應基本類型的包裝類型.

按照錯誤信息解決錯誤即可 最開始學習時,會遇到各種各樣的問題,我們要養(yǎng)成看錯誤?志的習慣,根據(jù)錯誤?志來解決問題

2.傳遞參數(shù)類型不匹配:狀態(tài)碼400

通過Fiddler觀察請求和響應, HTTP響應狀態(tài)碼為400

注意:對于包裝類型,如果不傳對應參數(shù),Spring接收到的數(shù)據(jù)則為null 所以企業(yè)開發(fā)中,對于參數(shù)可能為空的數(shù)據(jù),建議使?包裝類型

我們還可以用format進行代碼的格式化
@RequestMapping("/r4")
public String r3(String name, Integer age){
    return String.format("接受到參數(shù):姓名[%s], age[%d]", name, age);
}

作用是接收前端傳遞的nameage兩個參數(shù),并將接收到的參數(shù)拼接成字符串返回給前端。

Spring MVC 識別接口的核心是「請求路徑 + 請求方式(可選)」,而非方法名。

  1. Spring MVC 的映射核心:Spring MVC 會將@RequestMapping路徑、請求方式、請求參數(shù)、請求頭等信息組合成一個唯一的請求映射標識,只要這個標識不重復,即使方法名相同,也能被正確識別和調用。
  2. Java 方法的重載規(guī)則:上述示例中同名的r3方法,參數(shù)列表不同(如(String, Integer)(String)),這本身符合 Java 的方法重載規(guī)則(方法名相同,參數(shù)列表不同),因此編譯器也不會報錯。
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/param")
public class ParamController {
    // 路徑1:/param/r4,方法名r3
    @RequestMapping("/r4")
    public String r3(String name, Integer age) {
        return String.format("接受到參數(shù):姓名[%s], age[%d]", name, age);
    }
    // 路徑2:/param/r5,方法名同樣是r3(同名)
    @RequestMapping("/r5")
    public String r3(String address) {
        return "接收到參數(shù):地址[" + address + "]";
    }
    // 甚至可以路徑相同,但請求方式不同(如GET/POST),方法名也能相同
    @RequestMapping(value = "/r6", method = RequestMethod.GET)
    public String r3(String email) {
        return "GET請求:郵箱[" + email + "]";
    }
    @RequestMapping(value = "/r6", method = RequestMethod.POST)
    public String r3(String phone) {
        return "POST請求:手機號[" + phone + "]";
    }
}

2.4.2 傳遞多個參數(shù)

如何接收多個參數(shù)呢? 和接收單個參數(shù)?樣,直接使用?法的參數(shù)接收即可.使用多個形參

@RequestMapping("/m2")
public Object method2(String name, String password) {
return "接收到參數(shù)name:" + name + ", password:" + password;
}

使用瀏覽器發(fā)送請求并傳參:http://127.0.0.1:8080/param/m2?name=zhangsan&password=123456

當有多個參數(shù)時,前后端進?參數(shù)匹配時,是以參數(shù)的名稱進?匹配的,因此參數(shù)的位置是不影響后端獲取參數(shù)的結果.

比如訪問:http://127.0.0.1:8080/param/m2?password=123456&name=zhangsan 同樣可以拿到正 確的結果

可以看到,后端程序正確拿到了name和password參數(shù)的值

底層的邏輯是,先用這個特殊符號&進行分割,然后再從你的方法中看用到了啥,然后找到并且使用,所以這個順序是可以不一樣的但是名字必須是一樣的

詳細解釋:

一、先明確:參數(shù)傳遞的 “載體” 與分割符&的作用

當前端通過URL 參數(shù)(如/param/r4?name=張三&age=20)或表單提交傳遞參數(shù)時,參數(shù)的格式是key=value的鍵值對,多個參數(shù)之間用&分隔,&的核心作用就是分割不同的鍵值對參數(shù),這是 HTTP 協(xié)議規(guī)定的參數(shù)傳遞格式,和 Spring MVC 無關,但卻是 Spring 處理參數(shù)的前提。

舉個例子:name=張三&age=20 被&分割后,會得到兩個獨立的鍵值對:

  • name=張三(鍵:name,值:張三)
  • age=20(鍵:age,值:20)

二、Spring MVC 處理參數(shù)的核心步驟

Spring MVC 接收到分割后的鍵值對后,會按照以下邏輯匹配方法參數(shù),這也是參數(shù)名必須一致、順序可以任意的根本原因:

步驟 1:解析請求參數(shù),生成 “參數(shù)鍵值對映射表”

Spring 會先把所有請求參數(shù)(不管是 URL 里的、表單里的)解析成一個 **Map<String, String>結構的映射表 **(鍵是參數(shù)名,值是參數(shù)值)。比如上面的例子,映射表就是:

{
  "name": "張三",
  "age": "20"
}

步驟 2:根據(jù)方法的參數(shù)名,從映射表中 “按名取值”

Spring MVC 會獲取后端方法的參數(shù)名(如r3(String name, Integer age)中的nameage),然后根據(jù)參數(shù)名去映射表中查找對應的值,找到后再進行類型轉換(比如把字符串"20"轉成Integer類型),最后把值傳遞給方法參數(shù)。

三、為什么 “順序可以不一樣,名字必須一樣”?

1. 順序可以不一樣:因為參數(shù)是 “鍵值對”,不是 “位置依賴”

HTTP 參數(shù)是鍵值對結構,核心是key(參數(shù)名),而非參數(shù)在 URL 中的順序。比如:

  • /param/r4?name=張三&age=20
  • /param/r4?age=20&name=張三

這兩個請求的參數(shù)順序不同,但解析后的映射表完全一樣,Spring MVC 按名取值的結果也完全一樣,所以方法接收的參數(shù)值不會受影響。

2. 名字必須一樣:因為 Spring 是 “按名匹配”,不是 “按位置匹配”

如果前端傳遞的參數(shù)名和方法參數(shù)名不一致,Spring MVC 在映射表中找不到對應的鍵,參數(shù)值就會變成null(除非用@RequestParam指定別名)。比如:前端請求:/param/r4?username=張三&age=20(參數(shù)名是username,不是name)后端方法:public String r3(String name, Integer age)此時name參數(shù)會是null,因為映射表中只有username,沒有name這個鍵。

四、補充:如果想讓參數(shù)名不一致怎么辦?用@RequestParam指定別名

如果前端傳遞的參數(shù)名和后端方法參數(shù)名不一樣,可以通過@RequestParam注解顯式指定參數(shù)名的映射關系,這是實際開發(fā)中很常用的技巧:

@RequestMapping("/r4")
public String r3(
    @RequestParam("username") String name, // 前端傳username,后端用name接收
    Integer age
) {
    return String.format("接受到參數(shù):姓名[%s], age[%d]", name, age);
}

此時前端請求/param/r4?username=張三&age=20,就能正確接收到name=張三了。

2.4.3 傳遞對象

如果參數(shù)比較多時,方法聲明就需要有很多形參.并且后續(xù)每次新增?個參數(shù),也需要修改方法聲明. 我們不妨把這些參數(shù)封裝為?個對象. Spring MVC也可以自動實現(xiàn)對象參數(shù)的賦值,比如Person對象

如果參數(shù)比較多時,方法聲明就需要有很多形參.并且后續(xù)每次新增?個參數(shù),也需要修改方法聲明. 我們不妨把這些參數(shù)封裝為?個對象.

Spring MVC也可以?動實現(xiàn)對象參數(shù)的賦值,比如Person對象

public class Person {
    private int id;
    private String name;
    private String password;
    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 String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

傳遞對象代碼實現(xiàn):

    @RequestMapping("/m3")
    public Object method3(Person p){
        return p.toString();
    }

 使用瀏覽器發(fā)送請求并傳參:http://127.0.0.1:8080/param/m3?id=5&name=zhangsan&password=123456

Spring 會根據(jù)參數(shù)名稱自動綁定到對象的各個屬性上,如果某個屬性未傳遞,則賦值為null(基本類型則 賦值為默認初識值,比如int類型的屬性,會被賦值為0)

2.4.4 后端參數(shù)重命名(后端參數(shù)映射)

某些特殊的情況下,前端傳遞的參數(shù) key 和我們后端接收的 key 可以不一致,比如前端傳遞了一個 time 給后端,而后端是使用 createtime 字段來接收的,這樣就會出現(xiàn)參數(shù)接收不到的情況,如果出現(xiàn)這種情況,我們就可以使用 @RequestParam 來重命名前后端的參數(shù)值。

具體示例如下,后端實現(xiàn)代碼:

@RequestMapping("/r6")
public String r5(@RequestParam("sa") String name){
    return "接受到參數(shù): " + name;
}

可以看到,Spring 可以正確的把瀏覽器傳遞的參數(shù) time 綁定到了后端參數(shù)name 參數(shù)上此時,如果瀏覽器使用 name 進行參數(shù)傳遞呢?訪問 URL:

fildder的使用查看

可以得出結論:

  1. 使用@RequestParam進行參數(shù)重命名時,請求參數(shù)只能和@RequestParam聲明的名稱一致,才能進行參數(shù)綁定和賦值.
  2. 使用@RequestParam進行參數(shù)重命名時,參數(shù)就變成了必傳參數(shù).

非必傳參數(shù)設置如果我們的實際業(yè)務前端的參數(shù)是一個非必傳的參數(shù),針對上述問題,如何解決呢?先來了解下參數(shù)必傳的原因,我們查看@RequestParam注解的實現(xiàn)細節(jié)就可以發(fā)現(xiàn)端倪,注解實現(xiàn)如下:

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";
    @AliasFor("value")
    String name() default "";
    boolean required() default true;
    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}

可以看到required的默認值為 true, 表示含義就是:該注解修飾的參數(shù)默認為必傳既然如此,我們可以通過設置@RequestParam中的 required=false 來避免不傳遞時報錯,具體實現(xiàn)如下:

@RequestMapping("/m4")
public Object method4(@RequestParam(value = "time", required = false) String createtime) {
    return "接收到參數(shù)createtime:" + createtime;
}

可以看到,添加 required=false 之后,time 前面也加了 key, 變成了 value = "time"注解屬性賦值時,沒有指明 key 的話,默認為 value 屬性.如果需要有多個屬性進行賦值時,需要寫上 key

2.4.5 傳遞數(shù)組

Spring MVC可以?動綁定數(shù)組參數(shù)的賦值

后端實現(xiàn)代碼:

 @RequestMapping("/m5")
        public String method5(String[] arrayParam) {
            return "返回的數(shù)組:" + Arrays.toString(arrayParam);
        }

使用瀏覽器發(fā)送請求并傳參:數(shù)組參數(shù):請求參數(shù)名與形參數(shù)組名稱相同且請求參數(shù)為多個,后端定義數(shù)組類型形參即可接收參數(shù)

http://127.0.0.1:8080/param/m5?arrayParam=zhangsan&arrayParam=lisi&arrayParam=wangwu或者使用或者使用 http://127.0.0.1:8080/param/m5?arrayParam=zhangsan,lisi,wangwu瀏覽器響應結果:

可以看到后端對數(shù)組參數(shù)進行了正確的接收和響應.

或者使?Postman來發(fā)送請求

2.4.6 傳遞集合

2.4.6 傳遞集合集合參數(shù):和數(shù)組類似,同一個請求參數(shù)名有多個,且需要使用 @RequestParam 綁定參數(shù)關系默認情況下,請求中參數(shù)名相同的多個值,是封裝到數(shù)組。如果要封裝到集合,要使用@RequestParam 綁定參數(shù)關系請求方式和數(shù)組類似:

瀏覽器傳參:

方式一: http://127.0.0.1:8080/param/m6?listParam=zhangsan&listParam=lisi&listParam=wangwu

方式二::http://127.0.0.1:8080/param/m6?listParam=zhangsan%2clisi%2cwangwu

%2c 是逗號的轉義編碼,解碼后的 url 為: http://127.0.0.1:8080/param/m6listParam=zhangsan,lisi,wangwu

后端接收代碼:

 @RequestMapping ("/m6")
 public String method6 (@RequestParam List<String> listParam){
 return "size:"+listParam.size() + ",listParam:"+listParam;
 }

2.4.7 傳遞 JSON 數(shù)據(jù)

JSON 概念

JSON: JavaScript Object Notation【JavaScript 對象表示法】JSON 是一種輕量級的數(shù)據(jù)交互格式。它基于 ECMAScript (歐洲計算機協(xié)會制定的 js 規(guī)范) 的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數(shù)據(jù)。-- 百度百科簡單來說: JSON 就是一種數(shù)據(jù)格式,有自己的格式和語法,使用文本表示一個對象或數(shù)組的信息,因此JSON 本質是字符串。主要負責在不同的語言中數(shù)據(jù)傳遞和交換.

類似于:?國際通用語言 - 英語?中國 56 個民族不同地區(qū)的通用語言 - 普通話有自己的語法,其他語言也認識.

JSON 與 Javascript 的關系

沒有關系,只是語法相似,js 開發(fā)者能更快的上手而已,但是他的語法本身比較簡單,所以也很好學

JSON 語法

JSON 是一個字符串,其格式非常類似于 JavaScript 對象字面量的格式

我們先來看一段 JSON 數(shù)據(jù)

{
  "squadName": "Super hero squad",
  "homeTown": "Metro City",
  "formed": 2016,
  "secretBase": "Super tower",
  "active": true,
  "members": [
    {
      "name": "Molecule Man",
      "age": 29,
      "secretIdentity": "Dan Jukes",
      "powers": ["Radiation resistance", "Turning tiny", "Radiation blast"]
    },
    {
      "name": "Madame Uppercut",
      "age": 39,
      "secretIdentity": "Jane Wilson",
      "powers": ["Million tonne punch", "Damage resistance", "Superhuman reflexes"]
    },
    {
      "name": "Eternal Flame",
      "age": 1000000,
      "secretIdentity": "Unknown",
      "powers": ["Immortality", "Heat Immunity", "Inferno", "Teleportation", "Interdimensional travel"]
    }
  ]
}
  • 小隊基礎信息
    • "squadName": "Super hero squad":小隊名稱(超級英雄小隊)
    • "homeTown": "Metro City":家鄉(xiāng)(大都會城)
    • "formed": 2016:成立年份(2016 年)
    • "secretBase": "Super tower":秘密基地(超級塔樓)
    • "active": true:是否活躍(是)
  • 成員列表("members"是數(shù)組)數(shù)組里包含 3 個英雄對象,每個對象描述一個英雄的信息:
  • 第一個英雄(Molecule Man)
    • "name": "Molecule Man":姓名
    • "age": 29:年齡
    • "secretIdentity": "Dan Jukes":秘密身份
    • "powers": [...]:超能力(抗輻射、變小、輻射爆炸)
  • 第二個英雄(Madame Uppercut)
    • "name": "Madame Uppercut":姓名
    • "age": 39:年齡
    • "secretIdentity": "Jane Wilson":秘密身份
    • "powers": [...]:超能力(百萬噸拳、抗傷害、超人反應)
  • 第三個英雄(Eternal Flame)
    • "name": "Eternal Flame":姓名
    • "age": 1000000:年齡(100 萬歲)
    • "secretIdentity": "Unknown":秘密身份(未知)
    • "powers": [...]:超能力(永生、耐熱、地獄火、 teleportation、跨維度旅行)

可以壓縮表示

{"squadName":"Super hero squad","homeTown":"Metro City","formed":2016,"secretBase":"Super tower","active":true,"members":[{"name":"Molecule Man","age":29,"secretIdentity":"Dan Jukes","powers":["Radiation resistance","Turning tiny","Radiation blast"]},{"name":"Madame Uppercut","age":39,"secretIdentity":"Jane Wilson","powers":["Million tonne punch","Damage resistance","Superhuman reflexes"]},{"name":"Eternal Flame","age":1000000,"secretIdentity":"Unknown","powers":["Immortality","Heat Immunity","Inferno","Teleportation","Interdimensional travel"]}]}

JSON 的語法:

  1. 數(shù)據(jù)在 鍵值對 (Key/Value) 中
  2. 數(shù)據(jù)由逗號 , 分隔
  3. 對象用 {} 表示
  4. 數(shù)組用 [] 表示
  5. 值可以為對象,也可以為數(shù)組,數(shù)組中可以包含多個對象

JSON 的兩種結構

  1. 對象:大括號 {} 保存的對象是一個無序的 鍵值對 集合。一個對象以左括號 { 開始,右括號 } 結束。每個 "鍵" 后跟一個冒號 :,鍵值對使用逗號 , 分隔
  2. 數(shù)組:中括號 [] 保存的數(shù)組是值(value)的有序集合。一個數(shù)組以左中括號 [ 開始,右中括號 ] 結束,值之間使用逗號 , 分隔。

可 以使?在線JSON格式化?具來進?校驗和書寫:在線JSON校驗格式化?具(BeJSON)

JSON 字符串和 Java 對象互轉

JSON 本質上是一個字符串,通過文本來存儲和描述數(shù)據(jù)

Spring MVC 框架也集成了 JSON 的轉換工具,我們可以直接使用,來完成 JSON 字符串和 Java 對象的互轉本質上是 jackson-databind 提供的功能,Spring MVC 框架中已經(jīng)把該工具包引入了進來,咱們直接使用即可,如果脫離 Spring MVC 使用,需要引入相關依賴

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.5</version>
</dependency>

JSON 的轉換工具包有很多,jackson-databind 只是其中的一種. 

public class JSONUtils {
    private static ObjectMapper objectMapper = new ObjectMapper();
    public static void main(String[] args) throws JsonProcessingException {
        Person person = new Person();
        person.setId(5);
        person.setName("zhangsan");
        person.setPassword("123456");
        //對象轉為JSON字符串
        String jsonStr = objectMapper.writeValueAsString(person);
        System.out.println("JSON字符串為:"+jsonStr);
        //JSON字符串轉為對象
        Person p = objectMapper.readValue(jsonStr,Person.class);
        System.out.println("轉換的對象 id:"+p.getId()+",name:"+p.getName()+",password:"+p.getPassword());
    }
}

使用 ObjectMapper 對象提供的兩個方法,可以完成對象和 JSON 字符串的互轉

  • writeValueAsString: 把對象轉為 JSON 字符串
  • readValue: 把字符串轉為對象

JSON 優(yōu)點

  1. 簡單易用:語法簡單,易于理解和編寫,可以快速地進行數(shù)據(jù)交換
  2. 跨平臺支持: JSON 可以被多種編程語言解析和生成,可以在不同的平臺和語言之間進行數(shù)據(jù)交換和傳輸
  3. 輕量級:相較于 XML 格式,JSON 數(shù)據(jù)格式更加輕量級,傳輸數(shù)據(jù)時占用帶寬較小,可以提高數(shù)據(jù)傳輸速度
  4. 易于擴展: JSON 的數(shù)據(jù)結構靈活,支持嵌套對象和數(shù)組等復雜的數(shù)據(jù)結構,便于擴展和使用
  5. 安全性: JSON 數(shù)據(jù)格式是一種純文本格式,不包含可執(zhí)行代碼,不會執(zhí)行惡意代碼,因此具有較高的安全性

基于以上特點,JSON 在 Web 應用程序中被廣泛使用,如前后端數(shù)據(jù)交互、API 接口數(shù)據(jù)傳輸?shù)?

維度 / 格式ProtobufJSONXML
輕量級(評分)1(最優(yōu))2(中等)3(最差)
可讀性(評分)3(最差)2(中等)1(最優(yōu))
典型適用場景高性能 / 低空間要求的數(shù)據(jù)交互通用數(shù)據(jù)交互(兼顧輕量與可讀)配置文件(可讀性優(yōu)先)

傳遞 JSON 對象

接收 JSON 對象,需要使用 @RequestBody 注解

RequestBody: 請求正文,意思是這個注解作用在請求正文的數(shù)據(jù)綁定,請求參數(shù)必須在寫在請求正文中

后端實現(xiàn):

@RequestMapping(value = "/m7")
public Object method7(@RequestBody Person person) {
    return person.toString();
}

使用 Postman 來發(fā)送 json 請求參數(shù):

可以看到,后端正確接收了 通過Fiddler觀察?下請求參數(shù)

嘗試去除掉 @RequestBody 試試

@RequestMapping(value = "/m7")
public Object method7(Person person) {
return person.toString();
}

請求響應結果如下

后端未能成功給Person對象賦值.

2.4.8 獲取 URL 中參數(shù) @PathVariable

path variable: 路徑變量和字面表達的意思一樣,這個注解主要作用在請求 URL 路徑上的數(shù)據(jù)綁定默認傳遞參數(shù)寫在 URL 上,SpringMVC 就可以獲取到

后端實現(xiàn)代碼:

@RequestMapping("/m8/{id}/{name}")
public String method8(@PathVariable Integer id, @PathVariable("name") String userName){
    return "解析參數(shù)id:"+id+",name:"+userName;
}

使用瀏覽器發(fā)送請求: http://127.0.0.1:8080/param/m8/5/zhangsan或者使用 Postman 發(fā)送請求

  • @RequestMapping("/m8/{id}/{name}")
    • 這是 URL 路徑的占位符寫法:{id}{name}是路徑中的動態(tài)參數(shù)(占位符),表示訪問/m8/xxx/xxx時,xxx會被解析為對應的參數(shù)值。
  • 示例請求 URL:http://127.0.0.1:8080/m8/100/spring(此時id=100,name=spring)。
  • public String method8(@PathVariable Integer id, @PathVariable("name") String userName)
  • @PathVariable:Spring MVC 的注解,用于綁定 URL 路徑中的占位符參數(shù)到方法參數(shù)。
    • 第一個參數(shù)@PathVariable Integer id:路徑中{id}的參數(shù)值會直接綁定到id(因為參數(shù)名和占位符名稱一致)。
    • 第二個參數(shù)@PathVariable("name") String userName:路徑中{name}的參數(shù)值,通過("name")指定占位符名稱,綁定到方法參數(shù)userName(參數(shù)名和占位符名稱不一致時,必須顯式指定)。
  • return "解析參數(shù)id:"+id+",name:"+userName;
  • 將接收到的iduserName拼接成字符串返回,作為響應結果。

URL 傳參方式的驗證思路說明:

那我們看他是不是用了url進行傳參,就是把你給查詢字符串(?后面的東西刪除)

看看頁面還正常使用么,如果可以就是使用了

2.4.9 上傳文件 @RequestPart

后端代碼實現(xiàn):

@RequestMapping("/m9")
public String getfile(@RequestPart("file") MultipartFile file) throws IOException {
    //獲取文件名稱
    String fileName = file.getOriginalFilename();
    //文件上傳到指定路徑
    file.transferTo(new File("D:/temp/" + file.getOriginalFilename()));
    return "接收到文件名稱為: "+fileName;
}

使用 Postman 發(fā)送請求:

postman   form-data

  • 含義:多部分表單數(shù)據(jù)(對應 HTTP 的multipart/form-data格式)。
  • 用途:
    • 同時傳文件普通參數(shù)(比如上傳文件 + 傳字符串參數(shù));
    • 支持復雜數(shù)據(jù)結構(鍵值對、文件)。
  • 典型場景:文件上傳接口(比如你之前的@RequestPart接口)。

使用 Postman 發(fā)送請求:

2.4.10 獲取 Cookie/Session

回顧 CookieHTTP 協(xié)議

自身是屬于 "無狀態(tài)" 協(xié)議."無狀態(tài)" 的含義指的是:

默認情況下 HTTP 協(xié)議的客戶端和服務器之間的這次通信,和下次通信之間沒有直接的聯(lián)系.

但是實際開發(fā)中,我們很多時候是需要知道請求之間的關聯(lián)關系的.

例如登陸網(wǎng)站成功后,第二次訪問的時候服務器就能知道該請求是否是已經(jīng)登陸過了.

上述圖中的 “令牌” 通常就存儲在 Cookie 字段中.比如去醫(yī)院掛號

  1. 看病之前先掛號。掛號時候需要提供身份證號,同時得到了一張 "就診卡", 這個就診卡就相當于患者的 "令牌".
  2. 后續(xù)去各個科室進行檢查,診斷,開藥等操作,都不必再出示身份證了,只要憑就診卡即可識別出當前患者的身份.
  3. 看完病了之后,不想要就診卡了,就可以注銷這個卡。此時患者的身份和就診卡的關聯(lián)就銷毀了.(類似于網(wǎng)站的注銷操作)
  4. 又來看病,可以辦一張新的就診卡,此時就得到了一個新的 "令牌"

此時在服務器這邊就需要記錄 "令牌" 信息,以及令牌對應的用戶信息,這個就是 Session 機制所做的工作.

理解 Session

我們先來了解一下什么是會話.會話:對話的意思

在計算機領域,會話是一個客戶與服務器之間的不中斷的請求響應。對客戶的每個請求,服務器能夠識別出請求來自于同一個客戶。當一個未知的客戶向 Web 應用程序發(fā)送第一個請求時就開始了一個會話。當客戶明確結束會話或服務器在一個時限內沒有接受到客戶的任何請求時,會話就結束了.

比如我們打客服

電話每次打客服電話,是一個會話。

掛斷電話,會話就結束了下次再打客服電話,又是一個新的會話.

如果我們長時間不說話,沒有新的請求,會話也會結束.

服務器同一時刻收到的請求是很多的。服務器需要清楚的區(qū)分每個請求是屬于哪個用戶,也就是屬于哪個會話,就需要在服務器這邊記錄每個會話以及與用戶的信息的對應關系.

Session 是服務器為了保存用戶信息而創(chuàng)建的一個特殊的對象.

Session的本質就是?個"哈希表",存儲了?些鍵值對結構.Key就是SessionID,Value就是??信息(? ?信息可以根據(jù)需求靈活設計).

SessionId 是由服務器生成的一個 "唯一性字符串", 從 Session 機制的角度來看,這個唯一性字符串稱為 "SessionId". 但是站在整個登錄流程中看待,也可以把這個唯一性字符串稱為 "token".上述例子中的令牌 ID, 就可以看做是 SessionId, 只不過令牌除了 ID 之外,還會帶一些其他信息,比如時間,簽名等.

  1. 當用戶登陸的時候,服務器在 Session 中新增一個新記錄,并把 sessionId 返回給客戶端.(通過 HTTP 響應中的 Set-Cookie 字段返回).
  2. 客戶端后續(xù)再給服務器發(fā)送請求的時候,需要在請求中帶上 sessionId.(通過 HTTP 請求中的 Cookie 字段帶上).
  3. 服務器收到請求之后,根據(jù)請求中的 sessionId 在 Session 信息中獲取到對應的用戶信息,再進行后續(xù)操作。找不到則重新創(chuàng)建 Session, 并把 SessionID 返回

Session 默認是保存在內存中的.如果重啟服務器則Session數(shù)據(jù)就會丟失

Cookie 和 Session 的區(qū)別

  • Cookie 是客戶端保存用戶信息的一種機制. Session 是服務端保存用戶信息的一種機制.
  • Cookie 和 Session 之間主要是通過 SessionId 關聯(lián)起來的,SessionId 是 Cookie 和 Session 之間的橋梁
  • Cookie 和 Session 經(jīng)常會在一起配合使用。但是不是必須配合.
    • 完全可以用 Cookie 來保存一些數(shù)據(jù)在客戶端。這些數(shù)據(jù)不一定是用戶身份信息,也不一定是 SessionId
    • Session 中的 sessionId 也不需要非得通過 Cookie/Set-Cookie 傳遞,比如通過 URL 傳遞.

獲取Cookie

傳統(tǒng)獲取Cookie
   @RequestMapping("/getCookie")
    public String getCookie (HttpServletRequest request ,HttpServletresponse){
            Cookie[] cookies =  request.getCookies();
            StringBuilder stringBuilder = new StringBuilder();
if(cookies != null){
       for ( Cookie cookie :cookies) {
          stringBuilder.append("這個cookie 的名字是").append(cookie.getName()).append(cookie.getValue()).append("/n");
       }
       }else {
           stringBuilder.append("這個cookies 里面沒有任何值  ");
       }
         return stringBuilder.toString();
   }

F12開發(fā)者工具也很好用

補充說明

Spring MVC 是基于 Servlet API 構建的原始 Web 框架,也是在 Servlet 的基礎上實現(xiàn)的

HttpServletRequest , HttpServletResponse 是 Servlet 提供的兩個類,是 Spring MVC 方法的內置對象,需要時直接在方法中添加聲明即可.

HttpServletRequest 對象代表客戶端的請求,當客戶端通過 HTTP 協(xié)議訪問服務器時,HTTP 請求頭中的所有信息都封裝在這個對象中,通過這個對象提供的方法,可以獲得客戶端請求的所有信息.

HttpServletResponse 對象代表服務器的響應.HTTP 響應的信息都在這個對象中,比如向客戶端發(fā)送的數(shù)據(jù),響應頭,狀態(tài)碼等。通過這個對象提供的方法,可以獲得服務器響應的所有內容

Spring MVC 在這兩個對象的基礎上進行了封裝,給我們提供更加簡單的使用方法.

使用注解的傳遞單個Cookie
//使用注解傳遞的值
    @RequestMapping("/getTwoRequest")
    public String getCookie(@CookieValue("name") String cookie){
        return " 這個值是 " + cookie;
    }

獲取 Session

Session 存儲和獲取

Session 是服務器端的機制,我們需要先存儲,才能再獲取Session 也是基于 HttpServletRequest 來存儲和獲取的

Session 存儲
@RequestMapping("/setSess")
public String setsess(HttpServletRequest request) {
    // 獲取Session對象
    HttpSession session = request.getSession();
    if (session != null) {
        session.setAttribute("username", "java");
    }
    return "session 存儲成功";
}

獲取 Session 有兩種方式

HttpSession getSession(boolean create);
HttpSession getSession();
  • HttpSession getSession(boolean create):參數(shù)如果為 true,則當不存在會話時新建會話;參數(shù)如果為 false,則當不存在會話時返回 null
  • HttpSession getSession():和getSession(true)含義一樣,默認值為true。
  • void setAttribute(String name, Object value):使用指定的名稱綁定一個對象到該 session 會話

Session 讀取

讀取 Session 可以使用 HttpServletRequest

@RequestMapping("/getSess")
public String sess(HttpServletRequest request) {
    // 如果 session 不存在,不會自動創(chuàng)建
    HttpSession session = request.getSession(false);
    String username = null;
    if (session != null && session.getAttribute("username") != null) {
        username = (String) session.getAttribute("username");
    }
    return "username: " + username;
}
  • Object getAttribute(String name):返回在該 session 會話中具有指定名稱的對象,如果沒有指定名稱的對象,則返回 null。

運行

先設置 Session: http://127.0.0.1:8080/param/setSess

先設置Session:http://127.0.0.1:8080/param/setSess

通過Fiddler觀察Http請求和響應

可以看到,Http響應中,通過Set-Cookie告知客?端,把SessionID存儲在Cookie中 通過瀏覽器,可以觀察到運?結果:

可以看到,Http請求時,把SessionId通過Cookie傳遞到了服務器.

通過SpringMVC內置對象HttpSession來獲
@RequestMapping("/getSess2")
public String sess2(@SessionAttribute(value = "username",required = false)
String username) {
    return "username: "+username;
}

運行結果(getSess2)

地址:http://127.0.0.1:8080/param/getSess2頁面顯示:username: java

簡潔獲取 Session (2)

通過 Spring MVC 內置對象 HttpSession 來獲取

代碼 2

@RequestMapping("/getSess3")
public String sess3(HttpSession session) {
    String username = (String)session.getAttribute("username");
    return "username: "+username;
}

補充說明

HttpSession session = request.getSession();Session 不存在的話,會自動進行創(chuàng)建

運行結果(getSess3)

地址:http://127.0.0.1:8080/param/getSess3頁面顯示:username: java

2.4.11 獲取 Header

傳統(tǒng)獲取 header

獲取 Header 也是從 HttpServletRequest 中獲取

@RequestMapping("/param10")
public String param10(HttpServletRequest request, HttpServletResponse response)
{
    String userAgent = request.getHeader("User-Agent");
    return name + ":" + userAgent;
}
  • 使用 HttpServletRequest 提供的 getHeader 方法來獲取,參數(shù)對應 HTTP 請求報頭的 "Key"

運行結果:

補充說明

通過 Fiddler 觀察,獲取的 User-Agent 是否正確

簡潔獲取 Header

@RequestMapping("/header")
public String header(@RequestHeader("User-Agent") String userAgent) {
    return "userAgent: " + userAgent;
}
  • @RequestHeader注解的參數(shù)值為 HTTP 請求報頭中的 "Key"

運行結果

地址:http://127.0.0.1:8080/param/getHeader2

到此這篇關于Spring MVC 請求參數(shù)處理全解析的文章就介紹到這了,更多相關Spring MVC請求參數(shù)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 深度解析SpringBoot內嵌Web容器

    深度解析SpringBoot內嵌Web容器

    這篇文章主要給大家介紹SpringBoot的內嵌Web容器,SpringBoot將Web容器進行了內嵌,我們只需要將項目打成一個jar包,就可以運行了,大大省略了開發(fā)成本,那么SpringBoot是怎么實現(xiàn)的呢,我們今天就來詳細介紹
    2023-06-06
  • springboot不同環(huán)境使用不同配置文件打包方式

    springboot不同環(huán)境使用不同配置文件打包方式

    這篇文章主要介紹了springboot不同環(huán)境使用不同配置文件打包方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 基于bufferedreader的read()與readline()讀取出錯原因及解決

    基于bufferedreader的read()與readline()讀取出錯原因及解決

    這篇文章主要介紹了bufferedreader的read()與readline()讀取出錯原因及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java中UUID生成工具類(UUIDUtils)方法詳解

    java中UUID生成工具類(UUIDUtils)方法詳解

    這篇文章主要介紹了java中UUID生成工具類(UUIDUtils)的相關資料,UUIDUtils工具類是用于生成和處理UUID的工具類,支持生成標準UUID、去掉連字符的UUID、基于命名空間的UUID、UUID校驗和格式化等操作,需要的朋友可以參考下
    2025-05-05
  • Spring?MVC和springboot靜態(tài)資源處理問題

    Spring?MVC和springboot靜態(tài)資源處理問題

    這篇文章主要介紹了Spring?MVC和springboot靜態(tài)資源處理問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • elasticsearch 8.2.3 安裝及springboot簡單使用

    elasticsearch 8.2.3 安裝及springboot簡單使用

    這篇文章主要介紹了elasticsearch 8.2.3 安裝及springboot簡單使用,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • 關于SpringBoot mysql數(shù)據(jù)庫時區(qū)問題

    關于SpringBoot mysql數(shù)據(jù)庫時區(qū)問題

    在后端開發(fā)過程中經(jīng)常會遇到幾個時區(qū)設置問題,今天分幾種情況給大家介紹SpringBoot mysql數(shù)據(jù)庫時區(qū)問題,感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • 通過Spring Boot + Mybatis + Redis快速搭建現(xiàn)代化Web項目

    通過Spring Boot + Mybatis + Redis快速搭建現(xiàn)代化Web項目

    本篇文章介紹了如何通過Spring Boot、Mybatis以及Redis快速搭建一個現(xiàn)代化的Web項目,并且同時介紹了如何在Spring Boot下優(yōu)雅地書寫單元測試來保證我們的代碼質量。具體內容詳情大家通過本文學習下吧
    2017-12-12
  • SpringBoot整合ElasticSearch的示例代碼

    SpringBoot整合ElasticSearch的示例代碼

    本篇文章主要介紹了SpringBoot整合ElasticSearch的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • jackson 如何將實體轉json json字符串轉實體

    jackson 如何將實體轉json json字符串轉實體

    這篇文章主要介紹了jackson 實現(xiàn)將實體轉json json字符串轉實體,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評論

嘉峪关市| 漳州市| 甘肃省| 黄梅县| 忻城县| 莱州市| 耒阳市| 抚松县| 藁城市| 台东县| 凤阳县| 濮阳县| 华蓥市| 应城市| 建瓯市| 丰镇市| 邢台市| 盈江县| 文昌市| 龙江县| 敖汉旗| 凤冈县| 陆川县| 巴林左旗| 宁武县| 六盘水市| 安塞县| 楚雄市| 阳西县| 公主岭市| 保定市| 长垣县| 沈阳市| 石首市| 彩票| 尼木县| 临西县| 东至县| 双牌县| 泾川县| 休宁县|