Spring Boot 中的数据校验:@Valid 与 @Validated 的使用及统一异常处理
创始人
2024-11-14 23:04:28
0

在现代Web开发中,数据校验是确保应用安全性和稳定性的重要步骤。即使在前端已经进行了校验,后端仍需再次验证数据的合法性,以防止潜在的安全漏洞。Spring Boot 提供了多种方式来简化和标准化数据校验,包括 @Valid@Validated 注解。本篇博文将深入探讨如何在 Spring Boot 项目中使用这些注解,以及如何统一处理异常。

1. 引入依赖

根据 Spring Boot 的版本不同,数据校验的依赖引入方式有所不同。

1.1 Spring Boot 版本小于2.3

在 Spring Boot 2.3 版本之前,spring-boot-starter-web 依赖已经包含了校验所需的依赖包,因此不需要额外引入。

1.2 Spring Boot 版本大于等于2.3

从 Spring Boot 2.3 开始,需要手动引入校验相关的依赖。可以选择以下三种方式之一:

      org.springframework.boot     spring-boot-starter         javax.validation     validation-api     2.0.1.Final         org.hibernate.validator     hibernate-validator  

2. @Valid 和 @Validated 的用法和区别

2.1 @Valid 注解

  • 所属包:javax.validation.Valid
  • 用途:常用于校验方法参数和对象的字段,支持嵌套验证。
  • 适用场景:方法参数校验、成员属性(字段)校验。

2.2 @Validated 注解

  • 所属包:org.springframework.validation.annotation.Validated
  • 用途:Spring 提供的校验机制,可以用于方法参数校验和分组校验。
  • 适用场景:主要用于方法级别的参数校验,特别是当需要分组校验时。

3. 常用校验注解

以下是一些常用的校验注解及其用途:

  • @NotEmpty: 被注释的字符串不能为 null 或空。
  • @NotBlank: 被注释的字符串不能为 null,且必须包含至少一个非空白字符。
  • @NotNull: 被注释的元素不能为 null。
  • @AssertTrue: 被注释的元素必须为 true。
  • @Email: 被注释的元素必须是有效的 Email 格式。
  • @Min(value): 被注释的元素必须是一个数字,其值必须大于等于指定的最小值。
  • @Max(value): 被注释的元素必须是一个数字,其值必须小于等于指定的最大值。
  • @Size(max=, min=): 被注释的集合或数组的大小必须在指定的范围内。
  • @Past: 被注释的日期必须是过去的日期。
  • @Future: 被注释的日期必须是未来的日期。

4. 参数校验的实现

4.1 控制器层的校验

在控制器方法中使用 @Valid@Validated 注解,可以自动对传入的参数进行校验。例如:

@RestController @RequestMapping("/record") @Validated public class ReadRecordController {      @Autowired     private ReadRecordService readRecordService;      @PostMapping("/addRecord")     public ResponseResult addRecord(@RequestBody @Valid ReadRecord readRecord) {         return readRecordService.addRecord(readRecord);     }      @GetMapping("/getReadRecord")     public ResponseResult getReadRecord(@Valid @NotBlank(message = "fileCode不能传空值") String fileCode) {         return readRecordService.getReadRecord(fileCode);     } } 

4.2 实体类的校验注解

实体类中的字段可以使用校验注解进行约束,例如:

@Data public class ReadRecord {     private String id;      @NotBlank(message = "loginName不能传空")     private String loginName;      @NotBlank(message = "fileCode不能传空")     private String fileCode; } 

5. 自定义校验注解

当内置的校验注解不能满足需求时,可以自定义注解。例如,自定义一个校验手机号码格式的注解。

5.1 创建自定义注解

@Documented @Constraint(validatedBy = PhoneNumberValidator.class) @Target({FIELD, PARAMETER}) @Retention(RUNTIME) public @interface PhoneNumber {     String message() default "Invalid phone number";     Class[] groups() default {};     Class[] payload() default {}; } 

5.2 实现校验逻辑

public class PhoneNumberValidator implements ConstraintValidator {     @Override     public boolean isValid(String phoneField, ConstraintValidatorContext context) {         if (phoneField == null) {             return true;         }         return phoneField.matches("^1[3-9]\\d{9}$");     } } 

5.3 使用自定义注解

public class User {     @PhoneNumber(message = "phoneNumber 格式不正确")     @NotNull(message = "phoneNumber 不能为空")     private String phoneNumber; } 

6. 统一异常处理

为确保校验失败的错误信息能够正确返回给前端,我们需要进行统一的异常处理。可以通过 @ControllerAdvice@ExceptionHandler 来实现。

@ControllerAdvice public class CustomExceptionHandler {      @ExceptionHandler(MethodArgumentNotValidException.class)     @ResponseBody     public ResponseResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {         List allErrors = e.getBindingResult().getAllErrors();         List errorMessages = allErrors.stream()                 .map(ObjectError::getDefaultMessage)                 .collect(Collectors.toList());         return ResponseResult.errorResult(501, errorMessages.toString());     } } 

以上代码示例中,当 MethodArgumentNotValidException 异常被抛出时,CustomExceptionHandler 将捕获异常并返回格式化的错误信息。

7. 总结

在Spring Boot中,数据校验是确保数据完整性和安全性的关键环节。通过合理使用 @Valid@Validated 以及常用的校验注解,我们可以高效地实现数据校验。同时,结合自定义注解和统一异常处理机制,可以更好地满足实际项目中的特殊需求,并确保用户能够获得及时准确的反馈。

希望本篇文章能为您提供有价值的参考,帮助您在项目中更好地实现数据校验和异常处理。如果有任何问题或建议,欢迎交流和讨论。

相关内容

热门资讯

一分钟内幕!科乐吉林麻将系统发... 一分钟内幕!科乐吉林麻将系统发牌规律,福建大玩家确实真的是有挂,技巧教程(有挂ai代打);所有人都在...
一分钟揭秘!微扑克辅助软件(透... 一分钟揭秘!微扑克辅助软件(透视辅助)确实是有挂(2024已更新)(哔哩哔哩);1、用户打开应用后不...
五分钟发现!广东雀神麻雀怎么赢... 五分钟发现!广东雀神麻雀怎么赢,朋朋棋牌都是是真的有挂,高科技教程(有挂方法)1、广东雀神麻雀怎么赢...
每日必看!人皇大厅吗(透明挂)... 每日必看!人皇大厅吗(透明挂)好像存在有挂(2026已更新)(哔哩哔哩);人皇大厅吗辅助器中分为三种...
重大科普!新华棋牌有挂吗(透视... 重大科普!新华棋牌有挂吗(透视)一直是有挂(2021已更新)(哔哩哔哩)1、完成新华棋牌有挂吗的残局...
二分钟内幕!微信小程序途游辅助... 二分钟内幕!微信小程序途游辅助器,掌中乐游戏中心其实存在有挂,微扑克教程(有挂规律)二分钟内幕!微信...
科技揭秘!jj斗地主系统控牌吗... 科技揭秘!jj斗地主系统控牌吗(透视)本来真的是有挂(2025已更新)(哔哩哔哩)1、科技揭秘!jj...
1分钟普及!哈灵麻将攻略小,微... 1分钟普及!哈灵麻将攻略小,微信小程序十三张好像存在有挂,规律教程(有挂技巧)哈灵麻将攻略小是一种具...
9分钟教程!科乐麻将有挂吗,传... 9分钟教程!科乐麻将有挂吗,传送屋高防版辅助(总是存在有挂)1、完成传送屋高防版辅助透视辅助安装,帮...
每日必看教程!兴动游戏辅助器下... 每日必看教程!兴动游戏辅助器下载(辅助)真是真的有挂(2025已更新)(哔哩哔哩)1、打开软件启动之...