前言
在日常的 Web 开发中,请求参数校验是一个非常基础且重要的环节。通过校验,我们可以确保每次接口请求中,入参的数据是有效、安全且合规的,避免数据库中出现脏数据。
手动校验参数
原始的手动校验参数代码如下:
@PostMapping("/test")
@ApiOperationLog(description = "测试接口")
public ResponseEntity<String> test(@RequestBody User user) {
// 参数校验
if (user.getName() == null || user.getName().trim().isEmpty()) {
return ResponseEntity.badRequest().body("姓名不能为空");
}
if (user.getAge() < 18 || user.getAge() > 100) {
return ResponseEntity.badRequest().body("年龄必须在18到100之间");
}
if (user.getEmail() == null || !isValidEmail(user.getEmail())) {
return ResponseEntity.badRequest().body("邮箱格式不正确");
}
// 更多的校验...
// 返参
return ResponseEntity.ok("参数没有任何问题");
}
这还是只有 3 个字段需要校验的情况,如果更多呢?一堆的 if else
是不是又臭又长!有没有什么优雅的解决方案呢?
JSR 380 参数校验注解
Spring Boot 提供了简洁的方法,让我们能够利用 Java 校验 API (JSR 380) 中定义的注解进行参数校验。JSR 380,也被称为 Bean Validation 2.0,是 Java Bean 验证规范的一个版本。该规范定义了一系列注解,用于验证 Java Bean 对象的属性,确保它们满足某些条件或限制。
以下是 JSR 380 中提供的主要验证注解及其描述:
- @NotNull: 验证对象值不应为 null。
- @AssertTrue: 验证布尔值是否为 true。
- @AssertFalse: 验证布尔值是否为 false。
- @Min(value): 验证数字是否不小于指定的最小值。
- @Max(value): 验证数字是否不大于指定的最大值。
- @DecimalMin(value): 验证数字值(可以是浮点数)是否不小于指定的最小值。
- @DecimalMax(value): 验证数字值(可以是浮点数)是否不大于指定的最大值。
- @Positive: 验证数字值是否为正数。
- @PositiveOrZero: 验证数字值是否为正数或零。
- @Negative: 验证数字值是否为负数。
- @NegativeOrZero: 验证数字值是否为负数或零。
- @Size(min, max): 验证元素(如字符串、集合或数组)的大小是否在给定的最小值和最大值之间。
- @Digits(integer, fraction): 验证数字是否在指定的位数范围内。例如,可以验证一个数字是否有两位整数和三位小数。
- @Past: 验证日期或时间是否在当前时间之前。
- @PastOrPresent: 验证日期或时间是否在当前时间或之前。
- @Future: 验证日期或时间是否在当前时间之后。
- @FutureOrPresent: 验证日期或时间是否在当前时间或之后。
- @Pattern(regexp): 验证字符串是否与给定的正则表达式匹配。
- @NotEmpty: 验证元素(如字符串、集合、Map 或数组)不为 null,并且其大小/长度大于0。
- @NotBlank: 验证字符串不为 null,且至少包含一个非空白字符。
- @Email: 验证字符串是否符合有效的电子邮件格式。
除了上述的标准注解,JSR 380 也支持开发者定义和使用自己的自定义验证注解。此外,这个规范还提供了一系列的APIs和工具,用于执行验证和处理验证结果。大部分现代Java框架(如 Spring 和 Jakarta EE)都与 JSR 380 兼容,并支持其验证功能。
开始动手
引入依赖
首先,我们需要在 xx-web
模块中的 pom.xml
文件添加参数校验依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
实体类参数校验
package com.yanxiaosheng.xx.web.model;
import lombok.Data;
import javax.validation.constraints.*;
/**
* @author: 闫小生
* @url: www.yanxiaosheng.com
* @date: 2023-08-10 10:35
* @description: TODO
**/
@Data
public class User {
// 用户名
@NotBlank(message = "用户名不能为空") // 注解确保用户名不为空
private String username;
// 性别
@NotNull(message = "性别不能为空") // 注解确保性别不为空
private Integer sex;
// 年龄
@NotNull(message = "年龄不能为空")
@Min(value = 18, message = "年龄必须大于或等于 18") // 注解确保年龄大于等于 18
@Max(value = 100, message = "年龄必须小于或等于 100") // 注解确保年龄小于等于 100
private Integer age;
// 邮箱
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确") // 注解确保邮箱格式正确
private String email;
}
上述代码说明:
@NotBlank
: 此注解确保字符串不为空并且不能为空字符串,且去掉前后空格后的长度必须大于 0。它常用于字符串字段验证。message
属性用于指定提示信息;@NotNull
: 此注解确保整数类型不能为null
;@Min
和@Max
: 这两个注解用于验证数字值是否在指定的范围内。例如,在上面的示例中,我们想要确保age
的值在 18 到 100 之间;@Email
: 此注解用于验证字符串值是否是有效的电子邮件地址格式。
Controller 参数校验
针对每个字段的校验注解添加完成后,还需要在 controller
层进行捕获,并将错误信息返回。编辑 TestController
类,代码如下:
@RestController
@Slf4j
public class TestController {
@PostMapping("/test")
@ApiOperationLog(description = "测试接口")
public ResponseEntity<String> test(@RequestBody @Validated User user, BindingResult bindingResult) {
// 是否存在校验错误
if (bindingResult.hasErrors()) {
// 获取校验不通过字段的提示信息
String errorMsg = bindingResult.getFieldErrors()
.stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
return ResponseEntity.badRequest().body(errorMsg);
}
// 返参
return ResponseEntity.ok("参数没有任何问题");
}
}
解释一下上面代码中的关键部分:
@Validated
: 告诉 Spring 需要对User
对象执行校验;BindingResult
: 验证的结果对象,其中包含所有验证错误信息;
测试一下效果
使用 Postman 工具请求 /test
接口测试一下,请求入参如下:
入参正确的情况
入参:
{
"username": "闫小生",
"sex": 1,
"age": 32,
"email": "[email protected]"
}
入参不正确的情况
入参数据:
{
"username": "",
"sex": null,
"age": 120,
"email": "123124qq.com"
}
可以看到,在字段不符合校验规则的情况下,正确返回了每个字段的提示信息。参数校验功能正常执行。
标签:验证,Spring,Boot,校验,参数,是否,注解,message From: https://blog.csdn.net/m0_68207804/article/details/139823912