
- 前言
- 一. SpringBoot 集成参数校验
- 1. 引入依赖
- 2. 定义要进行参数校验的实体类
- 3. 定义校验类进行测试
- 4. 查看结果
- 5.统一异常处理器
- 6. 查看响应结果
- 二. 自定义参数校验
- 1. 创建自定义校验注解 EnumValue
- 2. 创建 EnumValue 校验注解处理类 EnumValuevalidator
- 3. 在字段上添加注解
- 4. 查询响应结果
- 三. 分组校验
- 1. 定义分组接口
- 2. 在模型中给参数添加分组
- 3. 给需要参数校验的方法指定分组
- 4. 查看响应结果
在日常开发过程中, 我们要对前端传过来的参数进行验证,防止一些非法参数对我们的业务造成影响。例如:登录的是否需要校验用户名密码是否为空,发送短信的时候要校验手机号格式是否正确,这个时候如果去用 if else 去一个个进行校验的就比较繁琐,代码的可读性就比较差
Validator 框架就是为了解决开发人员在开发的少写代码,注重业务逻辑的开发,validation 主要是校验用户提交的数据的合法性,比如是否为空,密码是否符合规则,邮箱格式是否正确等等…
2. 定义要进行参数校验的实体类org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-validation
@Data
public class User {
private String id;
@Length(min = 11,max = 11,message = "手机号格式不正确")
private String phone;
@NotBlank(message = "名字为必填项")
private String name;
@Email(message = "请填写正确的邮箱地址")
private String email;
@NotEmpty(message = "性别不能为空")
private String sex;
@NotNull(message = "年龄不能为空")
private Integer age;
}
常见的约束注解有:
@RestController
@Slf4j
@Validated
public class ValidController {
@PostMapping("/test1")
public String test1(@Validated @RequestBody User user){
return "test1 valid success";
}
@PostMapping("/test2")
public String test2(@Validated User user){
return "test2 valid success";
}
@PostMapping("/test3")
public String test3(@Email String email){
return "email valid success";
}
}
4. 查看结果
- 调用 test1 方法,查看响应
POST http://localhost:8080/test1
Content-Type: application/json
{
"id": 1,
"name": "十一",
"email": "898963",
"sex": "0",
"age": 22
}
{
"status": 500,
"message": "Validation failed for argument [0] in public java.lang.String com.fox.controller.ValidController.test1(com.fox.domain.User): [Field error in object 'user' on field 'email': rejected value [898963]; codes [Email.user.email,Email.email,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.email,email]; arguments []; default message [email],[Ljavax.validation.constraints.Pattern$Flag;@7476422b,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@78dedd82]; default message [请填写正确的邮箱地址]] ",
"data": null,
"timestamp": 1628239624332
}
- 调用test2方法,提示的是org.springframework.validation.BindException异常
POST http://localhost:8080/test2 Content-Type: application/x-www-form-urlencoded id=1&name=11&email=12345678&sex=0&age=22
{
"status": 500,
"message": "org.springframework.validation.BeanPropertyBindingResult: 1 errorsnField error in object 'user' on field 'email': rejected value [12345678]; codes [Email.user.email,Email.email,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.email,email]; arguments []; default message [email],[Ljavax.validation.constraints.Pattern$Flag;@7476422b,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@5116f8f3]; default message [请填写正确的邮箱地址]",
"data": null,
"timestamp": 1637489707831
}
- 调用test3方法,提示的是javax.validation.ConstraintViolationException异常
POST http://localhost:8080/test3 Content-Type: application/x-www-form-urlencoded email=3123123
{
"code": 500,
"message": "test3.email: 不是一个合法的电子邮件地址",
"data": null,
"timestamp": 1637489904002
}
通过加入 Validator 校验框架可以帮助我们自动实现参数的校验。
5.统一异常处理器Validator 校验框架返回的错误提示不方便阅读,为了便于阅读,我们需要对其进行简化。
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResultData validationErrorHandler(MethodArgumentNotValidException ex) {
String message = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
return ResultData.fail(message);
}
@ExceptionHandler(BindException.class)
@ResponseBody
public ResultData validationErrorHandler(BindException ex) {
String message = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
return ResultData.fail(message);
}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ResultData validationErrorHandler(ConstraintViolationException ex) {
String message = ex.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
return ResultData.fail(message);
}
6. 查看响应结果
POST http://localhost:8080/test1
Content-Type: application/json
{
"id": 1,
"name": "十一",
"email": "898963",
"sex": "0",
"age": 22
}
{
"code": 500,
"message": "请填写正确的邮箱地址",
"data": null,
"timestamp": 1637490231626
}
二. 自定义参数校验
1. 创建自定义校验注解 EnumValue
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@documented
@Constraint(validatedBy = {EnumValuevalidator.class})
public @interface EnumValue {
// 默认错误消息
String message() default "必须为指定值";
String[] strValues() default {};
int[] intValues() default {};
// 分组
Class>[] groups() default {};
// 负载
Class extends Payload>[] payload() default {};
// 指定多个时使用
@Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
@Retention(RUNTIME)
@documented
@interface List {
EnumValue[] value();
}
}
2. 创建 EnumValue 校验注解处理类 EnumValuevalidator
public class EnumValuevalidator implements ConstraintValidator3. 在字段上添加注解{ private String[] strValues; private int[] intValues; @Override public void initialize(EnumValue constraintAnnotation) { strValues = constraintAnnotation.strValues(); intValues = constraintAnnotation.intValues(); } @Override public boolean isValid(Object value, ConstraintValidatorContext context) { if (value instanceof String) { for (String s : strValues) { if (s.equals(value)) { return true; } } } else if (value instanceof Integer) { for (int s : intValues) { if (s == ((Integer) value).intValue()) { return true; } } } return false; } }
@ApiModelProperty(value = "性别")
@EnumValue(strValues = {"0","1"}, message="性别只能是0或者1")
private String sex;
4. 查询响应结果
{
"code": 500,
"message": "性别只能是0或者1",
"data": null,
"timestamp": 1637490878327
}
三. 分组校验
在实际开发中,难免遇到对一个实体类的一些属性,不同的请求会有不同的校验规则的场景。比如:用户注册时,User 类的 id 需要校验为空,因为 User 的 id 肯定是由系统维护而不是让用户自己填写,但是在修改密码的时候,又需要传入 id 去作为条件更新,此时,分组校验就派上用场了。
1. 定义分组接口
public class ValidationGroups {
public interface insert {
}
public interface update {
}
}
2. 在模型中给参数添加分组
public class User {
@NotBlank(groups = ValidationGroups.update.class)
@Null(groups = ValidationGroups.insert.class)
private int id;
}
3. 给需要参数校验的方法指定分组
@ApiOperation("新增")
@PostMapping("/add")
public String add(@Validated(value = ValidationGroups.insert.class) User user){
return "success";
}
4. 查看响应结果
POST http://localhost:8080/add
Content-Type: application/application/json
{
"name": "十一",
"email": "18790334713@163.com",
"sex": "0",
"age": 22
}
在 insert 时我们没有传递 id参数,校验通过。
当我们使用同样的参数调用 update 方法时则提示参数校验错误。
{
"code": 500,
"message": "id不能为空",
"data": null,
"timestamp": 1637491548612
}
代码地址: https://gitee.com/mingyangliang/spring-boot-validated
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)