Springboot使用validator进行参数校验
Posted 小妖云汐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Springboot使用validator进行参数校验相关的知识,希望对你有一定的参考价值。
Springboot使用validator进行参数校验
添加数据效验
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.15.Final</version>
</dependency>
单字段效验
- 添加效验注解
@Data
public class Users
private int id;
@NotBlank(message="用户名不能为空")
@Length(min = 1, max = 20, message = "用户名长度需要在20个字以内")
private String name;
@Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]9$", message = "手机号格式有误")
private String phone;
@Pattern(regexp="^[0-9]4-[0-9]2-[0-9]2$",message="出生日期格式不正确")
private String birthday;
@Email(message="请输入正确的邮箱")
private String email;
@Size(min = 1, max = 5)
private List<String> strings;
- 其他常用的注解
注解 | 说明 |
---|---|
@Range(min=最小值, max=最大值) | 验证注解的元素值在最小值和最大值之间 |
@Min(value=值) | 验证注解的元素值大于等于@Min指定的value值 |
@Max(value=值) | 验证注解的元素值小于等于@Max指定的value值 |
@Past | 验证注解的元素值(日期类型)比当前时间早 |
@Future | 验证注解的元素值(日期类型)比当前时间晚 |
@AssertFalse | 可以为null,如果不为null的话必须为false |
@AssertTrue | 可以为null,如果不为null的话必须为true |
@Digits | 设置必须是数字且数字整数的位数和小数的位数必须在指定范围内 |
级联效验
带校验的成员里存在级联对象时,也进行校验
@Data
public class Users
@Valid
private Collections collections;
分组效验与组序列
分组效验:将实体类的属性进行分组,标记后,在进行效验时,可以指定分组进行效验
组序列:指定分组执行效验的顺序,Default.class为默认分组
/****新增时,需要效验的字段分组****/
public interface AddGroup
/****更新时,需要效验的字段分组****/
public interface UpdateGroup
@Data
public class Collections
@NotBlank(message="修改时,id不能为空!",groups = UpdateGroup.class)
private int id;
@NotBlank(message="新增时,name不能为空!",groups = AddGroup.class)
private String name;
@NotBlank(message="新增和修改时,userid都不能为空!",groups = AddGroup.class,UpdateGroup.class)
private int userId;
private String content;
private String remark;
//组序列
@GroupSequence(Default.class, AddGroup.class, UpdateGroup.class)
public interface Group
多字段关联效验
场景描述:根据某个字段的值不同,对其他不同的属性进行效验
occupation字段为1时,说明该用户为学生,学校、入学时间、毕业时间为必填项
occupation字段为2时,说明该用户为在职员工,公司和职位为必填项
- 添加效验注解
@GroupSequenceProvider(UsersGroupSequenceProvider.class)
@Data
public class Users
private int occupation;//职业:学生 1 / 职工 2
@NotBlank(message = "学校不能为空!",groups = StudentGroup.class)
private String school;//学校
@NotNull(message = "入学时间为必填项!",groups = StudentGroup.class)
private Date admissionTime; //入学时间
@NotNull(message = "毕业时间为必填项!",groups = StudentGroup.class)
private Date graduationTime; //毕业时间
@NotNull(message = "公司不能为空!",groups = WorkGroup.class)
private String company; //公司
@NotNull(message = "职位不能为空!",groups = WorkGroup.class)
private String position;//职位
public interface StudentGroup
public interface WorkGroup
@GroupSequence(Default.class, StudentGroup.class, WorkGroup.class)
public interface Group
- 自定义分组序列提供器
实现DefaultGroupSequenceProvider接口,根据当前对象实例的occupation值,动态来决定加载哪些校验组进入默认校验组。
public class UsersGroupSequenceProvider implements DefaultGroupSequenceProvider<Users>
@Override
public List<Class<?>> getValidationGroups(Users users)
List<Class<?>> defaultGroupSequence = new ArrayList<>();
defaultGroupSequence.add(Users.class);
if (users != null)
int occupation = users.getOccupation();
if (occupation == 1) //为学生时,效验StudentGroup分组的字段
defaultGroupSequence.add(Users.StudentGroup.class);
else //为在职员工时,效验WorkGroup分组的字段
defaultGroupSequence.add(Users.WorkGroup.class);
return defaultGroupSequence;
执行数据效验
/**
* 统一结果类
*/
@Data
public class ResultCode
private Integer code;
private String msg;
public ResultCode(Integer code, String msg)
this.code = code;
this.msg = msg;
@Valid注解
处理validator异常
validator进行参数效验时,未通过效验会抛出MethodArgumentNotValidException异常,捕获并封装为统一结果类返回给前端。
@RestControllerAdvice
public class ResultExceptionHandler
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultCode handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
Map<String,String> errors = new HashMap<>();
e.getBindingResult().getAllErrors().forEach((error) ->
errors.put(((FieldError)error).getField(),error.getDefaultMessage());
);
return new ResultCode(500,errors.values().toString());
controller接口处理
使用@Valid注解进行参数效验,不指定具体分组
@RestController
@RequestMapping("/users")
public class UsersController
@PostMapping("checkUsers")
public ResultCode checkUsers(@RequestBody @Valid Users user)
//usersService.save(user);
return ResultCode.success();
ValidatorUtils工具类
自定义异常及处理
自定义参数效验异常:ParamException
public class ParamException extends RuntimeException
private int code = 500;
private String msg;
public ParamException()
super();
public ParamException(String msg)
super(msg);
this.msg = msg;
public ParamException(int code,String msg)
super(msg);
this.msg = msg;
this.code = code;
public ParamException(String msg, Throwable cause)
super(msg, cause);
this.msg = msg;
public int getCode()
return code;
public String getMsg()
return msg;
捕获自定义ParamException异常并封装为统一结果类返回给前端。
@RestControllerAdvice
public class ResultExceptionHandler
@ExceptionHandler(ParamException.class)
public ResultCode handleParamException(ParamException e)
return new ResultCode(e.getCode(),e.getMsg());
ValidatorUtils与接口
ValidatorUtils工具类,可以指定分组,或,只执行默认分组的效验
public class ValidatorUtils
private static Validator validator;
static
validator = Validation.buildDefaultValidatorFactory().getValidator();
/**
* 校验对象
* @param object 待校验对象
* @throws ParamException 校验不通过,则报ParamException异常
*/
public static void validateEntity(Object object)
throws ParamException
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, Default.class);
if (!constraintViolations.isEmpty())
ConstraintViolation<Object> constraint = constraintViolations.iterator().next();
throw new ParamException(constraint.getMessage());
/**
* 分组校验对象
* @param object 待校验对象
* @param groups 待校验的组
* @throws ParamException 校验不通过,则报ParamException异常
*/
public static void validateEntity(Object object, Class<?>... groups)
throws ParamException
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty())
ConstraintViolation<Object> constraint = constraintViolations.iterator().next();
throw new ParamException(constraint.getMessageTemplate());
controller接口调用ValidatorUtils方法进行效验,并传参分组
@PostMapping("checkUsersByGroup")
public ResultCode checkUsersByGroup(@RequestBody Users user)
ValidatorUtils.validateEntity(user,Users.Group.class);
//usersService.save(user);
return ResultCode.success();
以上是关于Springboot使用validator进行参数校验的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot入门二十二,使用Validation进行参数校验