前言
在实际开发过程中,我们经常会遇到各种不同的场景,需要从客户端接收不同的参数。Spring Boot 提供了多种方式来接收这些参数,使得我们的开发更加灵活便捷。这篇文章主要介绍了 SpringBoot 在接收参数的几种常用方式详解。随着前后端的分离,接口方式开发成为普遍的开发形式,前端相对于后端来说,常用的接口传参方式就一定要了解和熟悉。下面我们梳理了常用的几种 Controller 层接受参数的方式,需要的朋友可以参考下。
准备工作
打开 Spring Initializr 或者常用的 IDE,新建一个 Spring Boot 项目。接下来,我们将在这个项目中实现接收参数的功能。我们需要在 pom.xml
文件中添加 Spring Web 的依赖,打开 pom.xml
文件并添加以下依赖:
<dependencies>
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
接着,我们先定义一个类用来做参数接受类。在 src/main/java/org/dllwh/model
目录下创建一个名为 User.java
的文件,并添加如下内容:
import lombok.Data;
@Data
public class User {
private String userId;
private String userCode;
private String userName;
private String phone;
}
然后,我们再定义一个类用来做请求结果的统一返回类。在 src/main/java/org/dllwh/common
目录下创建一个名为 Result.java
的文件,并添加如下内容:
import lombok.Data;
@Data
public class Result<T> {
// 业务码。不是http状态码,200:成功,其余届时失败
private Integer code;
// 错误信息,如果业务成功,errMsg为空
private String errMsg;
// 响应数据
private T data;
private RestResult() {
super();
}
public static <T> Result success(T data) {
Result result = new Result<>();
result.setCode(200);
return result;
}
public static Result fail(String msg) {
Result result = new Result<>();
result.setCode(500);
result.setErrMsg(msg);
return result;
}
public static Result fail(int resultStatus, String msg) {
Result result = new Result<>();
result.setCode(resultStatus);
result.setErrMsg(msg);
return result;
}
}
一、Get 请求
1.1 以方法的形参接收参数
1.1.1 通过 @RequestParam 注解接收参数
参数用 @RequestParam
标注,用于将HTTP请求参数绑定到方法的参数上,这是最基本的一种。它可以帮助开发者轻松地获取和处理请求参数,从而简化控制器方法的编写。使用 @RequestParam
注解的方法参数默认为必填参数。这意味着,如果请求中没有该参数,就会报错。直接把请求参数写在Controller相应的方法的形参中,这种方式一般适用参数比较少的情况,
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@GetMapping("/param/query")
public Result<User> getParamByQuery(@RequestParam String name, @RequestParam String phone) {
log.info("name:{}", name);
log.info("phone:{}", phone);
return Result.success(null);
}
}
📌📌📌注意:Get 请求以方法的形式接收参数时,
@RequestParam
注解可以省略不写。关于@RequestParam
注解的用法及注意事项见附录 5.1。
1.1.2 数组、集合接收参数
-
数组参数:请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数。
@RestController @RequestMapping("/user") @Slf4j public class UserController { @GetMapping("/param/array") public Result<User> getParamByArray(String[] names) { Arrays.asList(names).forEach(System.out::println); return Result.success(null); } }
-
集合参数:请求参数名与形参集合名称相同且请求参数为多个,@RequestParam 绑定参数关系
@RestController @RequestMapping("/user") @Slf4j public class UserController { @GetMapping("/param/collection") public Result<User> getParamByCollection(@RequestParam List<String> names) { names.forEach(System.out::println); return Result.success(null); } }
📌📌SpringBoot 接收集合参数,需要用
@RequestParam
注解绑定参数,否则会报错!!
1.1.3 以实体类接收参数
如果需要同时接收一批数据,而不想通过普通方式一个个接收,就可以使用POJO对象的方式来获取提交过来的所有数据,只需要POJO对象的属性名和提交过来的参数一一对应上就可以了。注意:此场景适用于请求参数比较多的情况。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@GetMapping("/param/bean")
public Result<User> getParamByBeanObject(User user) {
log.info("name:{}", user.getUserName());
log.info("phone:{}", user.getPhone());
return Result.success(null);
}
}
上面是使用简单实体对象接收参数,只要请求参数名与形参对象属性名相同,定义POJO接收即可。而实际开发过程中,更多的是复杂实体对象,使用复杂实体对象接收参数时,不仅需要请求参数名与形参对象属性名相同,而且还需要按照对象层次结构关系即可接收嵌套POJO属性参数。例如:
📌📌📌注意:Get 请求以实体类接收参数时,不能用
@RequestParam
注解进行标注,因为不支持这样的方式获取参数。
1.1.4 通过 Map 接收参数
如果我们不想定义一个对象来接受参数,大可以使用Map来接收。使用 Map
来封装多个参数,而无需定义它们的名称(name)或数量。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
/**
* 接收 GET 请求的多个查询参数
*/
@GetMapping("/param/multi-query")
public Result<User> getParamByMultiQuery(@RequestParam Map<String, Object> map) {
System.out.println(map);
System.out.println(map.get("name"));
return Result.success(null);
}
}
1.2 通过 HttpServletRequest 接收参数
在方法的形参中定义 HttpServletRequest,通过原生的 HttpServletRequest 对象手动获取请求参数。【不推荐】
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@GetMapping("/param/httpServletRequest")
public Result<User> getParamByHttpServletRequest(HttpServletRequest request) {
String name = request.getParameter("name");
String phone = request.getParameter("phone");
log.info("name:{}", name);
log.info("phone:{}", phone);
return Result.success(null);
}
}
1.3 通过 @PathVariable 注解接收参数
@PathVariable 注解可用于处理请求 URI 映射中的模板变量,并将其绑定到 Controller 方法参数。注意:若方法参数名称和需要绑定的url中变量名称一致时,可以简写;若方法参数名称和需要绑定的url中变量名称不一致时,则需要转换。例如:
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
/**
* 接收路径变量
*/
@GetMapping("/param/PathVar/{id}/{phone}")
public Result<User> getParamByPathVar(@PathVariable("id") String userId, @PathVariable String phone) {
log.info("userId:{}", userId);
log.info("phone:{}", phone);
return Result.success(null);
}
}
📌📌注意:@PathVariable 的使用及注意事项与 @RequestParam 基本三是一致的,这里就不再过多阐述。
1.4 通过 @RequestHeader 接收参数
有些接口要求用请求头传递参数,比如使用token鉴权的系统,token一般都携带在请求头上,我们可以使用 @RequestHeader
注解来获取请求当中的请求头信息。例如:
-
获取单个header属性
@RestController @RequestMapping("/user") @Slf4j public class UserController { @GetMapping("/param/requestHeader") public Result<User> getParamByRequestHeader(@RequestHeader("token") String token) { log.info("token:{}", token); return Result.success(null); } }
📌📌📌注意:当header中不存在该参数时,系统会抛出的异常。
-
获取header对象
@RestController @RequestMapping("/user") @Slf4j public class UserController { @GetMapping("/param/requestHeader") public Result<User> getParamsByRequestHeader(@RequestHeader HttpHeaders headers) { log.info("token:{}", headers.get("token")); return Result.success(null); } }
1.5 通过 @CookieValue 接收参数
接受cookie参数,可以使用 @CookieValue
注解来接收
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@GetMapping(value = "/param/cookie")
public Result<User> getParamsByCookie(@CookieValue(name = "token") String token) {
log.info("token:{}", token);
return Result.success(null);
}
}
二、Post 请求
2.1 以方法的形参接收参数
2.1.1 RequestParam 注解接收参数
参数用 @RequestParam
标注,用于将HTTP请求参数绑定到方法的参数上,这是最基本的一种。它可以帮助开发者轻松地获取和处理请求参数,从而简化控制器方法的编写。注意:这种方式一般适用参数比较少的情况,而且被 @RequestParam
标注的参数,需要必传,否则会报错。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/query")
public Result<User> postParamByQuery(@RequestParam String name, @RequestParam String phone) {
log.info("name:{}", name);
log.info("phone:{}", phone);
return Result.success(null);
}
}
📌📌注:和 Get 请求一样,如果方法形参用
@RequestParam
注解标注,表示这个参数需要必传。
2.1.2 通过 Map 接收参数
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/multi")
public Result<User> postParamByMulti(@RequestParam Map<String, Object> map) {
System.out.println(map);
System.out.println(map.get("name"));
return Result.success(null);
}
}
2.2 通过 HttpServletRequest 接收参数
在方法的形参中定义 HttpServletRequest,通过原生的 HttpServletRequest 对象手动获取请求参数。【不推荐】
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/httpServletRequest")
public Result<User> postParamByHttpServletRequest(HttpServletRequest httpServletRequest) {
log.info("name:{}", httpServletRequest.getParameter("name"));
log.info("phone:{}", httpServletRequest.getParameter("phone"));
return Result.success(null);
}
}
2.3 以实体类接收参数
2.3.1 通过 param 提交参数
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/bean")
public Result<User> postParamByBeanObject(User user) {
log.info("name:{}", user.getUserName());
log.info("phone:{}", user.getPhone());
return Result.success(null);
}
}
📌📌注:Post 请求以实体类接收参数时,不能用
@RequestParam
注解进行标注,因为不支持这样的方式获取参数。
2.3.2 请求体以 form-data 提交参数
form-data 是表单提交的一种方式,比如常见的登录请求。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/form-data")
public Result<User> postParamByFormData(User user) {
log.info("name:{}", user.getUserName());
log.info("phone:{}", user.getPhone());
return Result.success(null);
}
}
2.3.3 请求体以 x-www-form-urlencoded 提交参数
x-www-form-urlencoded 也是表单提交的一种方式,只不过提交的参数被进行了编码,并且转换成了键值对。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/urlencoded")
public Result<User> postParamByUrlencoded(User user) {
log.info("name:{}", user.getUserName());
log.info("phone:{}", user.getPhone());
return Result.success(null);
}
}
2.4 通过 @PathVariable 注解进行接收
@PathVariable 注解可用于处理请求 URI 映射中的模板变量,并将其绑定到 Controller 方法参数。注意:若方法参数名称和需要绑定的url中变量名称一致时,可以简写;若方法参数名称和需要绑定的url中变量名称不一致时,则需要转换。例如:
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/PathVar/{name}")
public Result<User> getParamByPathVar(@PathVariable String name) {
log.info("name:{}", name);
return Result.success(null);
}
}
2.5 通过 @RequestBody 注解接收参数
📌📌注:
@RequestBody
注解主要用来接收前端传过来的请求体中的参数,并将其映射到一个对象上,需要使用POST请求,不能使用 Get 请求。
2.5.1 接收实体类参数
以实体类的方式接收body 的数据 【最常用】。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/requestBody/bean")
public Result<User> postRequestBodyParamByBean(@RequestBody User user) {
log.info("name:{}", user.getUserName());
log.info("phone:{}", user.getPhone());
return Result.success(null);
}
}
2.5.2 接收数组和集合
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/array")
public Result<User> postRequestBodyParamByArray(@RequestBody String[] names) {
Arrays.asList(names).forEach(System.out::println);
return Result.success(null);
}
}
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/collection")
public Result<User> postRequestBodyParamByCollection(@RequestBody List<String> names) {
names.forEach(System.out::println);
return Result.success(null);
}
}
2.5.3 通过 Map 接收参数
以Map的方式接收body 的数据。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/map")
public Result<User> postRequestBodyParamByMap(@RequestBody Map<String, Object> map) {
System.out.println(map);
System.out.println(map.get("name"));
return Result.success(null);
}
}
2.5.4 接收一个参数
以字符串的方式接收 body 的数据。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/param/")
public Result<User> postRequestBodyParam(@RequestBody String name) {
System.out.println(name);
return Result.success(null);
}
}
三、Delete 请求
3.1 以方法形参接收参数
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@DeleteMapping("/param/query")
public Result<User> deleteParamByQuery(@RequestParam String name) {
System.out.println(name);
return Result.success(null);
}
}
3.2 以实体类接收参数
📌📌注:需要用
@RequestBody
注解,否则接收的参数为 null。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@DeleteMapping("/param/bean")
public Result<User> deleteParamByBean(@RequestBody User user) {
System.out.println(user);
return Result.success(null);
}
}
3.3 以 map 接收参数
📌📌注:需要用
@RequestBody
注解,否则接收的参数为 null。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@DeleteMapping("/param/map")
public Result<User> deleteRequestBodyParamByMap(@RequestBody User user) {
System.out.println(user);
return Result.success(null);
}
}
3.4 @PathVariable 接收参数
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@DeleteMapping("/param/{name}")
public Result<User> deleteParamByPathVar(@PathVariable String name) {
System.out.println(name);
return Result.success(null);
}
}
四、Put 请求
五、附录
5.1 @RequestParam
除了基本用法,@RequestParam
还支持一些高级特性,帮助开发者更灵活地处理请求参数。
-
指定参数名:在某些情况下,请求参数的名称与方法参数的名称不一致。可以通过
@RequestParam
注解的value
属性指定请求参数的名称:@GetMapping("/info") public String sayHello(@RequestParam(value = "userName") String name) { return "Hello, " + name + "!"; }
-
设置默认值:在某些情况下,请求参数可能不存在或为空。可以通过
@RequestParam
注解的defaultValue
属性设置默认值,表示如果请求中没有同名参数时的默认值。@GetMapping("/hello") public String sayHello(@RequestParam(value = "userName", defaultValue = "World") String name) { return "Hello, " + name + "!"; }
-
处理可选参数:在某些情况下,请求参数是可选的。可以通过
@RequestParam
注解的required
属性设置参数是否为必填项,默认是true,表示请求中一定要有相应的参数,否则将异常;@GetMapping("/hello") public String sayHello(@RequestParam(value = "userName", required = false) String name) { if (name == null) { name = "World"; } return "Hello, " + name + "!"; }
-
处理多个参数:在某些情况下,可能需要处理多个请求参数。可以通过多个
@RequestParam
注解来实现:@GetMapping("/greet") public String greet(@RequestParam String name, @RequestParam int age) { return "Hello, " + name + "! You are " + age + " years old."; }
-
处理Date类型的参数:在某些情况下,请求参数可能是Date类型的,这个时候就需要加注解
@DateTimeFormat
@GetMapping("/greet") public String greet( @RequestParam(value="starTime", required= alse) @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") Date starTime, @RequestParam(value="endTime", required= alse) @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") Date endTime) { }