1. 概述

本文,我们将学习 Spring @RequestParam 注解用法及其属性配置。

@RequestParam 可用于获取query参数、表单参数,以及文件*。

2. 简单用法

假设我们有一个 /api/foos 接口,它接受一个名为 id 的查询参数:

@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam String id) {
    return "ID: " + id;
}

我们使用 @RequestParam 获取URL中的 id 查询参数。

GET 请求示例如下:

http://localhost:8080/spring-mvc-basics/api/foos?id=abc
----
ID: abc

@RequestParam 支持的属性包括:namevaluerequireddefaultValue,下面我们分别进行讲解

3. 指定请求参数名

默认请求参数名和变量名一样,可以使用 name 指定:

@PostMapping("/api/foos")
@ResponseBody
public String addFoo(@RequestParam(name = "id") String fooId, @RequestParam String name) { 
    return "ID: " + fooId + " Name: " + name;
}

使用 @RequestParam(value = "id")@RequestParam("id") 作用是一样的

4. 可选参数

@RequestParam 注解的参数默认是必传,如果缺失会报错:

GET /api/foos HTTP/1.1
-----
400 Bad Request
Required String parameter 'id' is not present

可设置 required 为false,非必传

@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam(required = false) String id) { 
    return "ID: " + id;
}

测试:

http://localhost:8080/spring-mvc-basics/api/foos?id=abc
----
ID: abc

and

http://localhost:8080/spring-mvc-basics/api/foos
----
ID: null

4.1. 使用 Java 8 Optional

也可以利用 Java8 Optional* 实现可选参数,而不用指定 required 属性:

@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam Optional<String> id){
    return "ID: " + id.orElseGet(() -> "not provided");
}

测试:

http://localhost:8080/spring-mvc-basics/api/foos 
---- 
ID: not provided

5. 参数默认值

通过 defaultValue 属性设置默认值:

@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam(defaultValue = "test") String id) {
    return "ID: " + id;
}

This is like required=false, in that the user no longer needs to supply the parameter:

http://localhost:8080/spring-mvc-basics/api/foos
----
ID: test

Although, we are still okay to provide it:

http://localhost:8080/spring-mvc-basics/api/foos?id=abc
----
ID: abc

Note that when we set the defaultValue attribute, required is indeed set to false.

6. 映射全部参数

We can also have multiple parameters without defining their names or count by just using a Map:

@PostMapping("/api/foos")
@ResponseBody
public String updateFoos(@RequestParam Map<String,String> allParams) {
    return "Parameters are " + allParams.entrySet();
}

which will then reflect back any parameters sent:

curl -X POST -F 'name=abc' -F 'id=123' http://localhost:8080/spring-mvc-basics/api/foos
-----
Parameters are {[name=abc], [id=123]}

7. 接受多值参数

A single @RequestParam can have multiple values:

@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam List<String> id) {
    return "IDs are " + id;
}

多个值之间以逗号分割:

http://localhost:8080/spring-mvc-basics/api/foos?id=1,2,3
----
IDs are [1,2,3]

或者直接:

http://localhost:8080/spring-mvc-basics/api/foos?id=1&id=2
----
IDs are [1,2]

8. 总结

In this article, we learned how to use @RequestParam.

The full source code for the examples can be found in the GitHub project.