数据校验的作用:不仅防止用户误输入,还能防止用户恶意的非法输入。
数据校验分类:

  1. 客户端校验:主要是 编写 JS代码完成数据校验
  2. 服务端校验:

Spring 自带的 Validation 校验框架
JSR303 (Java 验证规范) 本章重点讲解(推荐使用)
JSR303 是一个标准, Hibernate Validator 是对这个标准的实现

引入依赖

在 ruoyi-api-system 模块中引入依赖。为什么在这个模块中引入依赖?
因为本次要校验的 bean 对象是 SysUser 类,该类就在这个模块中。
后面我们会针对整个项目的依赖会合理规划一次,会将 spring-boot-starter-validation 依赖在 ruoyi-common-core 模块中引入(ruoyi-common-core作为最基础的模块,我们别写的模块都会直接或间接引入ruoyi-common-core)

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-validation</artifactId>
  4. </dependency>

编写Controller层代码

在代码中对前端传过来的 SysUser 对象进行数据校验,使用 @Validated 注解标注

  1. @RestController
  2. @RequestMapping("/user")
  3. @Slf4j
  4. public class SysUserController {
  5. @PostMapping
  6. public AjaxResult add(@Validated @RequestBody SysUser user) {
  7. if("admin".equals(user.getUserName())) {
  8. log.info("系统用户无法创建");
  9. return AjaxResult.error("系统用户无法创建");
  10. }
  11. log.info("调用了 add 方法添加用户");
  12. return AjaxResult.success("创建用户成功");
  13. }
  14. }

编写校验规则

对需要校验的 java bean 对象,在其 java bean 的属性上标注注解作为校验规则

  1. @Data
  2. public class SysUser implements Serializable {
  3. private static final long serialVersionUID = 1L;
  4. private Long userId;
  5. private String userName;
  6. @Size(min = 0, max = 5, message = "用户昵称长度不能超过5个字符")
  7. private String nickName;
  8. @Email
  9. private String email;
  10. }

测试

使用 postman 工具发送 post 请求
image.png
前台相应结果:
image.png
后台打印的日志:
image.png

优化

我们虽然使用了 Hibernate Validation 对 java bean 进行了数据校验,但当数据输入错误的时候,会抛出MethodArgumentNotValidException 异常,如果我们不捕获处理这个异常,那么就会出现上边的问题(报400错误)。结合我们全局异常处理器,我们可以针对 MethodArgumentNotValidException 异常进行捕获处理,给前台返回个友好提示。

GlobalExceptionHandler 类中添加 MethodArgumentNotValidException 异常的处理

  1. @RestControllerAdvice
  2. @Slf4j
  3. public class GlobalExceptionHandler {
  4. /**
  5. * 自定义验证异常
  6. */
  7. @ExceptionHandler(MethodArgumentNotValidException.class)
  8. public Object validExceptionHandler(MethodArgumentNotValidException e) {
  9. log.error(e.getMessage(), e);
  10. String message = e.getBindingResult().getFieldError().getDefaultMessage();
  11. return AjaxResult.error(message);
  12. }
  13. }

image.png
日志输出:
image.png
JSR 303 注解

注解 功能 范例
@Null 验证对象是否为 null @Null
String desc;
@NotNull 验证对象是否不为 null,无法检查长度为0的字符串 @NotNull
String name;
@NotBlank 检查字符串是不是 null,且 trim后长度是否大于0。只作用于字符串,且会去掉前后空格 @NotBlank
String name;
@AssertTrue 验证 Boolean 对象是否为 true @AssertTrue
boolean isEmpty;
@AssertFalse 验证 Boolean 对象是否为 false @AssertFalse
boolean isEmpty;
@Max(value) 验证 Number 和 String 对象是否小于等于指定值 @Max(18)
int age;
@Min(value) 验证 Number 和 String 对象是否大于等于指定值 @Min(60)
int age;
@DecimalMax(value) 验证 BigDecimal 对象不大于指定值 @DecimalMax(1.1)
BigDecimal price;
@DecimalMin(value) 验证 BigDecimal 对象不小于指定值 @DecimalMin(0.5)
BigDecimal price;
@Digits(integer,fraction) 验证字符串是否符合指定格式的数字,integer 指定整数精度,fraction指定小数精度 @Digits(integer=5,fraction=2)
@BgiDecimal price
@Size 验证对象(Array,Collection,Map,String)长度是否在给定范围之内 @Size(min=15,max=60)
int age
@Email 验证是否是合法的邮件地址 @Email
String email;
@Past 验证 Date 和 Calendar 对象是否在当前时间之前 @Past
Date birthDate;
@Future 验证 Date 和 Calendar 对象是否在当前时间之后 @Future
Date birthDate;
@Pattern 验证 String 对象是否符合正则表达式规则 @Pattern(regexp=”[1][3,8][3,6,9][0-9]{8}”)
String phone

Hibernate Validator 扩展的注解

注解 功能 范例
@URL 验证是否是合法 URL @URL
String url;
@CreditCardNumber 验证是否是合法的信用卡号码 @CreditCardNumber
String cireditCard;
@Length(min, max) 验证字符串的长度必须在指定的范围内 @Length(min=6, max=8)
String password;
@NotEmpty 检查元素是否为 Null 或 Empty。用于 Array、Collection、Map、String @NotEmpty
String name;
@Range(min,max,message) 验证属性值必须在合适的范围内 @Range(min=19, max=60, message=”学生的年龄必须在18到60岁之间”
int age;