知識庫 / Spring / Spring MVC RSS 訂閱

從HttpServletRequest中獲取查詢字符串參數

Spring MVC
HongKong
9
11:19 AM · Dec 06 ,2025

1. 引言

後端 HTTP API 開發中最重要的一項能力之一是解析前端傳遞的請求查詢參數。

在本教程中,我們將介紹幾種直接從 <em >HttpServletRequest</em> 中獲取查詢參數的方法,以及 Spring MVC 提供的簡潔方法。

2. 使用 HttpServletRequest 中的方法

首先,讓我們看看 HttpServletRequest 提供的與參數相關的各種方法。

2.1. HttpServletRequest#getQueryString()

此示例展示了通過調用方法 <emHttpServletRequest#getQueryString()</em> 直接從 URL 中獲取內容:

@GetMapping("/api/byGetQueryString")
public String byGetQueryString(HttpServletRequest request) {
    return request.getQueryString();
}

當我們使用 curl 向該 API 發送帶有多個參數的 GET 請求時,方法 getQueryString() 僅僅返回 ‘?’ 之後的所有字符:

$ curl 'http://127.0.0.1:8080/spring-mvc-basics/api/byGetQueryString?username=bob&roles=admin&roles=stuff'
username=bob&roles=admin&roles=stuff

請注意,如果我們將 @GetMapping 更改為 @RequestMapping,則在通過 POST/PUT/PATCH/DELETE HTTP 方法發送請求時,將返回相同的響應。這意味着 HttpServletRequest 將始終獲取查詢字符串,無論 HTTP 方法如何。因此,我們可以在本教程中僅關注 GET 請求。為了簡化我們演示 HttpServletRequest 提供的方法,我們將在以下所有示例中使用相同的請求參數。

2.2. <em>HttpServletRequest#getParameter(String)</em>

為了簡化參數解析,<em>HttpServletRequest</em> 提供了一個方法 getParameter,用於通過參數名稱獲取其值:

@GetMapping("/api/byGetParameter")
public String byGetParameter(HttpServletRequest request) {
    String username = request.getParameter("username");
    return "username:" + username;
}

當我們發送一個帶有查詢字符串 username=bob的 GET 請求時,getParameter(“username”) 調用會返回 bob

$ curl 'http://127.0.0.1:8080/spring-mvc-basics/api/byGetParameter?username=bob&roles=admin&roles=stuff'
username:bob

2.3. `HttpServletRequest#getParameterValues

該方法 getParameterValuesgetParameter 方法類似,但返回一個 String[] 而不是一個 String。 這是因為 HTTP 規範允許使用相同的名稱傳遞多個參數。

@GetMapping("/api/byGetParameterValues")
public String byGetParameterValues(HttpServletRequest request) {
    String[] roles = request.getParameterValues("roles");
    return "roles:" + Arrays.toString(roles);
}

因此,當我們通過參數 roles 兩次傳遞值時,我們應該在數組中得到兩個值:

$ curl 'http://127.0.0.1:8080/spring-mvc-basics/api/byGetParameterValues?username=bob&roles=admin&roles=stuff'
roles:[admin, stuff]

2.4. HttpServletRequest#getParameterMap()

假設我們有以下 UserDto POJO 作為以下 JSON API 示例的一部分:

public class UserDto {
    private String username;
    private List<String> roles;
    // standard getter/setters...
}

如我們所見,可以有多個不同參數名稱,每個名稱對應一個或多個值。對於這些情況,HttpServletRequest 提供了另一個方法 getParameterMap(),它返回一個 Map<String, String[]>。該方法允許我們使用 Map 來獲取參數值。

@GetMapping("/api/byGetParameterMap")
public UserDto byGetParameterMap(HttpServletRequest request) {
    Map parameterMap = request.getParameterMap();
    String[] usernames = parameterMap.get("username");
    String[] roles = parameterMap.get("roles");
    UserDto userDto = new UserDto();
    userDto.setUsername(usernames[0]);
    userDto.setRoles(Arrays.asList(roles));
    return userDto;
}

我們將會收到一個 JSON 響應:

$ curl 'http://127.0.0.1:8080/spring-mvc-basics/api/byGetParameterMap?username=bob&roles=admin&roles=stuff'
{"username":"bob","roles":["admin","stuff"]}

3. 使用 Spring MVC 獲取參數

讓我們看看 Spring MVC 如何改善在解析查詢字符串時的編碼體驗。

3.1. 參數名稱

使用 Spring MVC 框架,我們無需手動使用 <em >HttpServletRequest</em > 直接解析參數。 在第一個案例中,我們定義了一個具有兩個參數的方法,參數名稱分別為 <em >username</em ><em >roles</em >>,從而避免了使用 <em >HttpServletRequest</em >>,Spring MVC 會自動處理。

@GetMapping("/api/byParameterName")
public UserDto byParameterName(String username, String[] roles) {
    UserDto userDto = new UserDto();
    userDto.setUsername(username);
    userDto.setRoles(Arrays.asList(roles));
    return userDto;
}

這將返回與最後一個示例相同的結果,因為我們使用了相同的模型:

$ curl 'http://127.0.0.1:8080/spring-mvc-basics/api/byParameterName?username=bob&roles=admin&roles=stuff'
{"username":"bob","roles":["admin","stuff"]}

3.2. @RequestParam

如果 HTTP 查詢參數名稱與 Java 方法參數名稱不同,或者方法參數名稱在編譯後的字節碼中不會被保留,則可以使用註解 @RequestParam 來配置方法參數名稱。

例如,我們使用 @RequestParam(“username”)@RequestParam(“roles”),如下所示:

@GetMapping("/api/byAnnoRequestParam")
public UserDto byAnnoRequestParam(@RequestParam("username") String var1, @RequestParam("roles") List<String> var2) {
    UserDto userDto = new UserDto();
    userDto.setUsername(var1);
    userDto.setRoles(var2);
    return userDto;
}

並進行測試:

$ curl 'http://127.0.0.1:8080/spring-mvc-basics/api/byAnnoRequestParam?username=bob&roles=admin&roles=stuff'
{"username":"bob","roles":["admin","stuff"]}

3.3. POJO

我們可以更簡單地直接使用 POJO 作為參數類型:

@GetMapping("/api/byPojo")
public UserDto byPojo(UserDto userDto) {
    return userDto;
}

Spring MVC 可以自動解析參數、創建 POJO 實例並將其填充所需參數。

$ curl 'http://127.0.0.1:8080/spring-mvc-basics/api/byPojo?username=bob&roles=admin&roles=stuff'
{"username":"bob","roles":["admin","stuff"]}

最後,我們使用單元測試來確保最後四種方法提供完全相同的功能。

@ParameterizedTest
@CsvSource(textBlock = """
    /api/byGetParameterMap
    /api/byParameterName
    /api/byAnnoRequestParam
    /api/byPojo
    """)
public void whenPassParameters_thenReturnResolvedModel(String path) throws Exception {
    this.mockMvc.perform(get(path + "?username=bob&roles=admin&roles=stuff"))
      .andExpect(status().isOk())
      .andExpect(jsonPath("$.username").value("bob"))
      .andExpect(jsonPath("$.roles").value(containsInRelativeOrder("admin", "stuff")));
}

4. 結論

在本文中,我們介紹瞭如何使用 Spring MVC 從 HttpServletRequest 中獲取參數的方法。通過這些示例,我們可以看到,使用 Spring MVC 解析參數時,可以顯著減少代碼量。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.