数据校验的作用:不仅防止用户误输入,还能防止用户恶意的非法输入。
数据校验分类:
- 客户端校验:主要是 编写 JS代码完成数据校验
- 服务端校验:
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)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
编写Controller层代码
在代码中对前端传过来的 SysUser 对象进行数据校验,使用 @Validated 注解标注
@RestController
@RequestMapping("/user")
@Slf4j
public class SysUserController {
@PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user) {
if("admin".equals(user.getUserName())) {
log.info("系统用户无法创建");
return AjaxResult.error("系统用户无法创建");
}
log.info("调用了 add 方法添加用户");
return AjaxResult.success("创建用户成功");
}
}
编写校验规则
对需要校验的 java bean 对象,在其 java bean 的属性上标注注解作为校验规则
@Data
public class SysUser implements Serializable {
private static final long serialVersionUID = 1L;
private Long userId;
private String userName;
@Size(min = 0, max = 5, message = "用户昵称长度不能超过5个字符")
private String nickName;
private String email;
}
测试
使用 postman 工具发送 post 请求
前台相应结果:
后台打印的日志:
优化
我们虽然使用了 Hibernate Validation 对 java bean 进行了数据校验,但当数据输入错误的时候,会抛出MethodArgumentNotValidException 异常,如果我们不捕获处理这个异常,那么就会出现上边的问题(报400错误)。结合我们全局异常处理器,我们可以针对 MethodArgumentNotValidException 异常进行捕获处理,给前台返回个友好提示。
在 GlobalExceptionHandler 类中添加 MethodArgumentNotValidException 异常的处理
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
* 自定义验证异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Object validExceptionHandler(MethodArgumentNotValidException e) {
log.error(e.getMessage(), e);
String message = e.getBindingResult().getFieldError().getDefaultMessage();
return AjaxResult.error(message);
}
}
日志输出:
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 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; |