@Validated是干嘛的?
在实际写项目的过程中,相信大家对一些表单字段的校验并不陌生,比如?
一个前端的登录注册表单,你可能需要对用户名密码的长度进行限制或者对邮箱以及手机号码进行正则校验等。
但是大家都知道,仅仅依靠前端进行参数的判断是绝对不行的,市面上的很多请求工具postman这些都是直接绕过前端发送请求的。
很好解决,前后端双重校验不就行了?在没有阅读这篇文章的时候,你可以会这样写:
@GetMapping("/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password) {
if (username == null) {
return "用户名不能为空";
}
if (password== null) {
return "密码不能为空";
}
return "success";
}
这仅仅是两个参数,随着需求的变更,前端传过来的字段越来越多,你的if代码可能堆成shi山了吧。
@Validated
介绍一下:
Spring Validation验证框架对参数的验证机制提供了@Validated
(Spring’s JSR-303规范,是标准JSR-303的一个变种),配合BindingResult可以直接提供参数验证结果。
简单点说,if else屎山代码的拯救者。
javax提供了
@Valid
(标准JSR-303规范)。
上面两个注解我都用过,功能和用法大差不差,它们的区别就是
@Validated
支持分组校验,@Valid
不支持,所以这里我们讲解@Validated
注解。
一个简单的例子教你如何使用
在接收参数的实体类中的属性上添加以下注解
@Data
public class LoginFormVo {
@NotEmpty(message = "用户名不能为空")
private String username;
@NotEmpty(message = "密码不能为空")
private String password;
}
这里的message方法用来定义在对应字段校验失败的时候返回的提示,往下看你会明白。
对应的Controller方法
@GetMapping("/login")
public R login(@Validated LoginFormVo loginFormVo, BindingResult result) {
Map<String, String> map = null;
// 字段校验异常 ----> true
if (result.hasErrors()) {
// 获取校验失败的字段
List<FieldError> fieldErrors = result.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
// 获取该字段校验失败后提示的信息,也就是我们实体类中定义的message
String message = fieldError.getDefaultMessage();
System.out.println(message);
}
}
return R.ok();
}
在方法参数中需要校验的实体前面添加@Validated
注解,并且添加BindingResult参数,获取我们参数校验的结果。
使用postman工具进行测试,携带两个空字符串的参数发送请求:
结果:
常用校验注解
除了使用的@NotEmpty
注解,其实还有很多校验注解,如下:
@NotNull
:被注释的元素必须不为 null
@Min(value)
:被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)
:被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min)
:被注释的元素的大小必须在指定的范围内,用在集合大小或者字符串的大小
@Pattern(value)
:被注释的元素必须符合指定的正则表达式
@NotEmpty
:被注释的元素必须不为 null 或者不为空,可校验字符、集合、Map
@NotBlank
:被注释的元素必须不为空字符串
@Range(min ,max)
:数值类型的范围大小,相当于@Min+@Max两个注解
@NotEmpty和@NotNull的区别:
- @NotEmpty:当传递的值为空或空字符串 “” 时,也会校验异常。
- @NotNull:只有传递的值为null时会捕获,如果前端传递空字符串"",不会捕获。
- @NotEmpty不能作用与数值类型的属性。
@Data
public class RegisterFormVo {
@NotEmpty(message = "用户名不能为空")
private String username;
@NotEmpty(message = "密码不能为空")
private String password;
@NotEmpty(message = "手机号码不能为空")
@Pattern(regexp = "^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$", message = "手机号码格式错误")
private String Phone;
@NotEmpty(message = "姓名不能为空")
private String nickname;
@Min(value = 0, message = "错误的性别参数") // 0和1
@Max(value = 1, message = "错误的性别参数")
private Integer gender;
}
分组校验
很多情况下我们需要使用到分组校验,比如在修改时,id不能为空,而在新增时,id必须为空,这种情况下就需要使用到分组校验,对不同情况下,属性采用不同校验规则。
步骤:
- 在相关校验规则注解内添加属性groups指定分组。
- 定义这些分组接口
public interface AddGroup { } // ------------------------ public interface UpdateGroup { }
这里定义即可,不需要写任何接口逻辑,只是作为一个组的标识。
例如,上述的BrandId就表示,在新增操作时,该属性必须为空;在修改操作时,该属性必须不为空。 - 在controller使用
@Validated
注解来指定当前请求体参数使用哪个分组规则。