赞
踩
接口参数是导致很多BUG产生的始作俑者,原因在于接口参数有3多:接口参数的取值地方多,如查询参数(Query Parameters)、路径参数(Path Parameters)、请求体(Request Body)等;数据类型多,如数字、字符、日期、文件等;判断情况多,如空值判断、格式判断、大小判断等;
示例代码如下:
- @GetMapping("/testParams1")
- public ResponseEntity<String> testParams1(String param1, Integer param2) {
- return ResponseEntity.ok(MessageFormat.format("param1:[{0}];param2:[{1}]", param1, param2));
- }
调用请求:http://localhost:8080/testParams1?param1=111¶m2=222
返回如下:
没啥坑。
示例代码如下
- @GetMapping("/testParams2")
- public ResponseEntity<String> testParams2(ParamsReq paramsReq) {
- return ResponseEntity.ok(MessageFormat.format("param1:[{0}];param2:[{1}]", paramsReq.getParam1(), paramsReq.getParam2()));
- }
ParamsReq.java
- public class ParamsReq {
-
- private String param1;
-
- private String param2;
-
- public ParamsReq() {
- }
-
- public ParamsReq(String param1, String param2) {
- this.param1 = param1;
- this.param2 = param2;
- }
-
- public String getParam1() {
- return param1;
- }
-
- public void setParam1(String param1) {
- this.param1 = param1;
- }
-
- public String getParam2() {
- return param2;
- }
-
- public void setParam2(String param2) {
- this.param2 = param2;
- }
-
- @Override
- public String toString() {
- return "ParamsReq{" +
- "param1='" + param1 + '\'' +
- ", param2='" + param2 + '\'' +
- '}';
- }
- }
调用请求:http://localhost:8080/testParams2?param1=111¶m2=222
返回如下:
这种有一个坑,Spring默认使用无参构造函数来实例化对象,所以ParamsReq不能是接口、抽象类等特殊类。
示例代码如下:
- @PostMapping("/testParams3")
- public ResponseEntity<String> testParams3(ParamsReq paramsReq) {
- return ResponseEntity.ok(MessageFormat.format("param1:[{0}];param2:[{1}]", paramsReq.getParam1(), paramsReq.getParam2()));
- }
ParamsReq类代码同上
和GET请求类似,没啥坑。
没啥坑。
这里有坑了,当content-type为application/json时,接口参数取值为空。这时就需要在参数前加上一个注解:
@RequestBody
,原因是通过@RequestBody
注解,Spring Boot可以自动地将请求体中的JSON数据转换为Java对象,从而方便地进行数据的处理和转换。如果不加@RequestBody
注解,Spring Boot默认会将请求体中的JSON数据作为普通的表单数据来处理,而不会自动转换为Java对象。:
改成这样就行:
public ResponseEntity<String> testParams3(@RequestBody ParamsReq paramsReq)
示例代码如下:
- @GetMapping("/testParams4/{pathParam}")
- public ResponseEntity<String> testParams4(@PathVariable("pathParam") String pathParam) {
- return ResponseEntity.ok(MessageFormat.format("pathParam:[{0}];", pathParam));
- }
参数使用
{
和}
框起来,然后使用@PathVariable
即可获取到值,坑不多。
这两种情况里面的参数主要是标识类的参数如userToken,一般都是不变的,业务中很少使用到。
没啥坑。
示例代码如下:
- @GetMapping("/testParams5")
- public ResponseEntity<String> testParams5(Date date) {
- return ResponseEntity.ok(MessageFormat.format("pathParam:[{0}];", date));
- }
这里有个问题,这样的接口前端怎么传这个
date
值,字符串?时间戳?我已经替大家试过了,都不行,接口直接报400。
正确的做法是在日期参数前加上@DateTimeFormat注解,改成这样就行了:
public ResponseEntity<String> testParams5(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date)
。
传参的话传字符串:2023-09-14 00:00:00 即可
示例代码如下:
- @GetMapping("/testParams6")
- public ResponseEntity<String> testParams6(List<Integer> paramList) {
- return ResponseEntity.ok(MessageFormat.format("paramList:[{0}];", paramList));
- }
这串代码不用测试,它本身就是错误的,前面说过Spring默认使用无参构造函数来实例化对象,但是List是一个接口,没有无参构造函数。
为了解决这个问题,可以使用Spring的@RequestParam
注解来指定参数名,并将多个参数值绑定到一个List对象中。
修改代码如下:
public String testParams6(@RequestParam("paramList") List<Integer> paramList)
即可
然后,通过使用逗号分隔的参数值来访问接口,如:http://localhost:8080/testParams6?paramList=1,2,3
这样就可以成功传递参数列表并访问接口了。
先写一个简单上传界面
upload.html
- <!DOCTYPE html>
- <html>
- <head>
- <title>File Upload Demo</title>
- </head>
- <body>
- <h1>File Upload Demo</h1>
- <form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
- <input type="file" name="file" />
- <br/><br/>
- <input type="submit" value="Upload" />
- </form>
- </body>
- </html>
后端上传代码
FileUploadController.java
- import org.springframework.http.HttpStatus;
- import org.springframework.http.ResponseEntity;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.multipart.MultipartFile;
-
- @Controller
- public class FileUploadController {
-
- @PostMapping("/upload")
- public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
- // Check if file is empty
- if (file.isEmpty()) {
- return new ResponseEntity<>("File is empty", HttpStatus.BAD_REQUEST);
- }
-
- // Save the file
- try {
- byte[] bytes = file.getBytes();
- // Logic to save the file to a desired location
-
- return new ResponseEntity<>("File uploaded successfully", HttpStatus.OK);
- } catch (Exception e) {
- return new ResponseEntity<>("Failed to upload file", HttpStatus.INTERNAL_SERVER_ERROR);
- }
- }
- }
上传接口后端其实还好,主要是前端需要处理的内容多一些,由于MultipartFile类也是一个接口,所以这里也需要加上
@RequestParam
注解。
前面提到的@RequestBody
、@RequestParam
注解都是SpringBoot自带的,它们主要的功能是将请求参数转换为我们接口定义的变量或者Java对象,而校验参数值是否合法通常有下面几种做法:
@NotNull
、@NotBlank
这里主要讲一下javax.validation如何使用!
- <!-- 接口参数校验 -->
- <dependency>
- <groupId>javax.validation</groupId>
- <artifactId>validation-api</artifactId>
- <version>2.0.1.Final</version>
- </dependency>
注解 | 说明 | 使用频率 |
---|---|---|
@NotNull | 不能为null,常用于数字、日期 | 常用 |
@NotBlank | 不能为null也不能为空,常用于字符串 | 常用 |
@NotEmpty | 集合不能为空,常用于List、Map、Set | 常用 |
注解 | 说明 | 使用频率 |
---|---|---|
@Max | 被注释的元素必须小于等于指定的值 | 常用 |
@Min | 被注释的元素必须大于等于指定的值 | 常用 |
@Positive | 被注释的元素必须是正数 | 不常用 |
@Negative | 被注释的元素必须是负数 | 不常用 |
注解 | 说明 | 使用频率 |
---|---|---|
@AssertFalse | 被注释的元素必须是false | 常用 |
@AssertTrue | 被注释的元素必须是true | 常用 |
注解 | 说明 | 使用频率 |
---|---|---|
@Future | 被注释的元素必须是将来的日期 | 不常用 |
@Past | 被注释的元素必须是过去的日期 | 不常用 |
注解 | 说明 | 使用频率 |
---|---|---|
被注释的元素必须是电子邮箱地址 | 常用 | |
@Pattern | 被注释的元素必须是符合正则表达式,我经常使用这个判断手机号是否合法 | 常用 |
下面是一个经典的案例
- @Data
- public class StudentReq {
- @NotBlank(message = "主键不能为空")
- private String id;
- @NotBlank(message = "名字不能为空")
- @Size(min = 2, max = 4, message = "名字字符长度必须为 2~4个")
- private String name;
- @Pattern(regexp = "^1[3456789]\\d{9}$", message = "手机号格式错误")
- private String phone;
- @Email(message = "邮箱格式错误")
- private String email;
- @Past(message = "生日必须早于当前时间")
- private Date birth;
- @Min(value = 0, message = "年龄必须为 0~100")
- @Max(value = 100, message = "年龄必须为 0~100")
- private Integer age;
- @PositiveOrZero
- private Double score;
- }
这些东西看看就行了,用的时候翻一下文档就行,记也记不住。
这些对象可以直接在接口参数上使用,通过框架自动注入的方式获取其实例。在使用时,需要保证框架已经正确配置和启用了对应的注解和拦截器。用的最多的就是HttpServletRequest和HttpServletResponse了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。