网站首页 > 技术文章 正文
在当今的互联网软件开发领域,Spring Boot 框架凭借其强大的功能和便捷的开发体验,成为了众多开发者构建 Web 应用的首选。随着版本迭代到 Spring Boot3,其在参数校验方面的优化和升级,为开发者提供了更高效、更可靠的手段来确保数据的合法性和完整性。今天,就让我们深入探究一下 Spring Boot3 中如何对 Post 请求传入的 Body 对象进行参数合法性校验。
参数校验的重要性
在 Web 应用开发中,参数校验是保障系统稳定性和安全性的重要环节。想象一下,假如没有对用户通过 Post 请求提交的数据进行严格校验,那么可能会出现各种问题。非法的参数可能导致程序抛出异常,使应用程序崩溃,严重影响用户体验。例如,一个电商系统中,如果商品数量被恶意篡改提交了一个负数,可能会导致库存出现负数,进而影响整个业务流程。又或者错误的数据进入数据库,破坏数据的完整性和一致性,给后续的数据分析和业务决策带来极大的困扰。所以,我们必须重视参数校验,为系统筑牢第一道防线。
开启参数校验的准备工作
要在 Spring Boot3 项目中开启参数校验功能,首先需要在项目的pom.xml文件中引入
spring-boot-starter-validation依赖。这个依赖基于强大的 Hibernate Validator 实现,就如同为我们开启了参数校验的大门,提供了全面且便捷的参数校验支持。在pom.xml文件中添加如下依赖代码:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
引入这个依赖后,Spring Boot3 就已经为我们搭建好了参数校验的基础环境,接下来我们就可以利用各种校验工具和注解来实现具体的校验逻辑了。
Spring Boot3 的内置校验注解
Spring Boot3 为我们提供了丰富多样的内置校验注解,这些注解是进行参数校验的得力工具,它们各自具备独特的功能,能够满足我们在不同场景下的校验需求。
@NotBlank:用于验证字符串不能为空且不能仅由空白字符组成。例如,在用户注册场景中,用户名通常不允许为空且不能全是空格,我们可以在对应的实体类属性上添加这个注解。
@NotEmpty:可用于验证字符串、集合、数组等不为空。比如在一个任务管理系统中,任务列表不能为空,就可以使用该注解进行校验。
@NotNull:主要用于验证基本数据类型的包装类、对象等不为空。像在订单系统中,订单编号一般不能为空,就可以用它来校验。
@Max和@Min:用于验证数值类型的参数是否在指定的最大值和最小值范围内。例如,商品的折扣力度可能需要限制在一定的数值区间内,这时就可以使用这两个注解。
@Range:同样用于验证数值范围,与 @Max 和 @Min 不同的是,它可以同时指定最大值和最小值,使用起来更加简洁。
@Email:专门用于验证邮箱格式的正确性。在用户注册时验证用户输入的邮箱地址是否合法,这个注解就派上用场了。
@Pattern:可以通过正则表达式来验证字符串是否匹配指定的模式。比如校验手机号码格式等场景,就可以使用它来实现自定义的格式校验。
定义需要校验的实体类
当我们了解了这些内置校验注解后,就可以在实体类中使用它们来定义参数的校验规则。以一个用户注册的场景为例,假设我们有一个UserRegisterDTO实体类,代码如下:
public class UserRegisterDTO {
@NotBlank(message = "用户名不能为空")
private String username;
@NotBlank(message = "密码不能为空")
private String password;
@Email(message = "邮箱格式不正确")
private String email;
@Pattern(regexp = "^1[3-9]\\d{9}#34;, message = "手机号码格式不正确")
private String phone;
// 生成getter和setter方法
}
在这个实体类中,我们在每个属性上添加了相应的校验注解,并通过message属性来指定校验失败时返回给前端的错误信息。这样,当用户通过 Post 请求提交注册信息时,Spring Boot3 就会根据这些注解来校验请求体中的数据是否合法。
在 Controller 中编写校验逻辑
在定义好需要校验的实体类后,接下来我们要在 Controller 层中编写校验逻辑。在 Controller 的接口方法中,通过@Valid或@Validated注解来触发参数校验。
使用 @Valid 注解
@Valid注解就像是一个启动器,当请求进入 Controller 层方法时,它会促使 Spring Boot3 开始对参数进行校验。以下是一个简单的示例:
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("/register")
public Result registerUser(@Valid @RequestBody UserRegisterDTO userRegisterDTO) {
// 这里开始处理正常的业务逻辑,比如将用户信息保存到数据库
return Result.success("注册成功");
}
}
在这个例子中,我们在registerUser方法的参数userRegisterDTO前添加了@Valid注解,并且该参数使用@RequestBody注解来接收 Post 请求中的 JSON 格式数据。当请求到达这个方法时,Spring Boot3 会自动检查userRegisterDTO中的各个字段是否符合在实体类中定义的校验规则。如果校验通过,就会执行方法内的业务逻辑;如果校验失败,Spring Boot3 会抛出
MethodArgumentNotValidException异常。
使用 @Validated 注解
@Validated注解也是 Spring Boot3 中用于参数校验的重要注解,与@Valid相比,它具有一些独特的优势。@Validated不仅可以用在方法参数上进行校验,还支持分组校验功能,这使得它在处理复杂业务场景时更加灵活。例如,在一个用户信息管理系统中,用户信息的更新和创建可能需要不同的校验规则。我们可以定义不同的校验分组,然后在实体类和 Controller 方法中使用@Validated注解来指定不同的分组。以下是一个简单的示例:
首先定义校验分组接口:
public interface CreateGroup {}
public interface UpdateGroup {}
然后在实体类中根据不同的分组添加校验注解:
public class UserDTO {
@NotNull(groups = UpdateGroup.class, message = "用户ID在更新时不能为空")
private Long id;
@NotBlank(groups = {CreateGroup.class, UpdateGroup.class}, message = "用户名不能为空")
private String username;
// 其他属性及getter和setter方法
}
在 Controller 中使用@Validated注解并指定分组:
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("/create")
public Result createUser(@Validated(CreateGroup.class) @RequestBody UserDTO userDTO) {
// 创建用户的业务逻辑
return Result.success("用户创建成功");
}
@PutMapping("/update")
public Result updateUser(@Validated(UpdateGroup.class) @RequestBody UserDTO userDTO) {
// 更新用户的业务逻辑
return Result.success("用户更新成功");
}
}
通过这种方式,我们可以根据不同的业务场景,灵活地应用不同的校验规则,提高了代码的可维护性和扩展性。
获取校验结果并进行错误处理
当参数校验失败时,Spring Boot3 会抛出
MethodArgumentNotValidException异常。为了给前端返回友好的错误提示,我们需要对这个异常进行统一处理。在 Spring Boot3 中,我们可以通过创建一个全局异常处理类,并使用@ControllerAdvice注解来实现全局异常处理。以下是一个全局异常处理类的示例代码:
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
List<String> errorMessages = new ArrayList<>();
e.getBindingResult().getAllErrors().forEach(error -> {
errorMessages.add(error.getDefaultMessage());
});
return Result.error("参数校验失败", errorMessages);
}
}
在这个全局异常处理类中,我们定义了一个
handleMethodArgumentNotValidException方法,该方法使用@ExceptionHandler注解来捕获
MethodArgumentNotValidException异常。在方法内部,我们从异常中获取所有的校验错误信息,并将这些信息封装成一个Result对象返回给前端。这样,前端就能够清晰地接收到参数校验失败的具体原因,方便进行错误提示和用户交互。
自定义校验注解
在一些复杂的业务场景中,Spring Boot3 提供的内置校验注解可能无法满足我们的全部需求。这时,我们可以自定义校验注解来实现更灵活、更个性化的参数校验。自定义校验注解通常需要以下几个步骤:
定义注解
首先创建一个新的注解类,在注解类上使用@Constraint注解来指定该注解的校验器,同时可以添加一些属性来定制校验规则和错误提示信息。以下是一个自定义手机号码校验注解的示例:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneNumberValidator.class)
public @interface PhoneNumber {
String message() default "手机号码格式不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
在这个注解定义中,@Target注解指定了该注解可以应用在字段和方法参数上,@Retention注解指定了注解在运行时保留,@Constraint注解指定了该注解的校验器为
PhoneNumberValidator.class。
实现校验器
创建一个实现了ConstraintValidator接口的校验器类,在这个类中实现具体的校验逻辑。以下是PhoneNumberValidator校验器的实现代码:
public class PhoneNumberValidator implements ConstraintValidator<PhoneNumber, String> {
@Override
public void initialize(PhoneNumber constraintAnnotation) {
// 初始化方法,可以在这里获取注解的属性值等信息
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return value.matches("^1[3-9]\\d{9}#34;);
}
}
在isValid方法中,我们实现了具体的手机号码格式校验逻辑,只有当输入的字符串符合手机号码的正则表达式格式时,才返回true,表示校验通过。
在实体类中使用自定义注解
定义好注解和校验器后,就可以在实体类中使用自定义注解了。例如:
public class UserDTO {
@PhoneNumber
private String phone;
// 其他属性及getter和setter方法
}
通过这种方式,我们就实现了自定义的参数校验注解,能够在实际开发中满足各种复杂的业务校验需求。
总结
在 Spring Boot3 的开发过程中,对 Post 请求传入的 Body 对象进行参数合法性校验是保障应用程序质量和稳定性的重要环节。通过引入
spring-boot-starter-validation依赖,使用丰富的内置校验注解,结合@Valid和@Validated注解在 Controller 层触发校验,以及通过全局异常处理类统一处理校验失败的异常,我们可以有效地防止非法参数对应用程序的破坏。同时,自定义校验注解功能为我们提供了更灵活的扩展方式,满足各种复杂业务场景的校验需求。
同时掌握这些参数校验的方法和技巧,不仅可以提高我们开发的应用程序的可靠性,还能提升代码的可读性、可维护性和可扩展性,让我们在互联网软件开发的道路上更加游刃有余。希望本文的内容能够对各位开发者在 Spring Boot3 开发中进行参数校验有所帮助,大家可以在实际项目中不断实践和探索,将参数校验的优势发挥到极致。
猜你喜欢
- 2025-07-28 如何优雅的实现 Spring Boot 接口参数加密解密?
- 2025-07-28 SpringBoot注解最全详解(9大常用注解)
- 2025-07-28 SpringBoot注解全攻略:这些注解让你的代码更专业!
- 2025-07-28 后端使用技术 —— 规范统一入口方法
- 2025-07-28 答应我,不要再用 Map 做出入参了好吗
- 2025-07-28 关于远程调用feign的优雅写法(feign远程调用怎么用restful)
- 2025-07-28 自研分布式高性能RPC框架及服务注册中心ApiRegistry实践笔记
- 2025-07-28 spring基础面试题整理(2)(spring基本面试题)
- 2025-07-28 Spring Boot异常处理太难搞,这样实现让你轻松应对!
- 2025-07-28 独立开发:高效集成大模型,看这篇就够了
- 1520℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 617℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 524℃MySQL service启动脚本浅析(r12笔记第59天)
- 490℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 490℃启用MySQL查询缓存(mysql8.0查询缓存)
- 478℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 458℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 457℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)