Springboot使用validator进行参数校验

2023-10-17 12:01:40

添加数据效验

<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>

单字段效验

  • 添加效验注解
@DatapublicclassUsers{privateint id;@NotBlank(message="用户名不能为空")@Length(min=1, max=20, message="用户名长度需要在20个字以内")privateString name;@Pattern(regexp="^[1][3,4,5,6,7,8,9][0-9]{9}$", message="手机号格式有误")privateString phone;@Pattern(regexp="^[0-9]{4}-[0-9]{2}-[0-9]{2}$",message="出生日期格式不正确")privateString birthday;@Email(message="请输入正确的邮箱")privateString email;@Size(min=1, max=5)privateList<String> strings;}
  • 其他常用的注解
注解说明
@Range(min=最小值, max=最大值)验证注解的元素值在最小值和最大值之间
@Min(value=值)验证注解的元素值大于等于@Min指定的value值
@Max(value=值)验证注解的元素值小于等于@Max指定的value值
@Past验证注解的元素值(日期类型)比当前时间早
@Future验证注解的元素值(日期类型)比当前时间晚
@AssertFalse可以为null,如果不为null的话必须为false
@AssertTrue可以为null,如果不为null的话必须为true
@Digits设置必须是数字且数字整数的位数和小数的位数必须在指定范围内

级联效验

带校验的成员里存在级联对象时,也进行校验

@DatapublicclassUsers{@ValidprivateCollections collections;}

分组效验与组序列

分组效验:将实体类的属性进行分组,标记后,在进行效验时,可以指定分组进行效验
组序列:指定分组执行效验的顺序,Default.class为默认分组

/****新增时,需要效验的字段分组****/publicinterfaceAddGroup{}/****更新时,需要效验的字段分组****/publicinterfaceUpdateGroup{}@DatapublicclassCollections{@NotBlank(message="修改时,id不能为空!",groups=UpdateGroup.class)privateint id;@NotBlank(message="新增时,name不能为空!",groups=AddGroup.class)privateString name;@NotBlank(message="新增和修改时,userid都不能为空!",groups={AddGroup.class,UpdateGroup.class})privateint userId;privateString content;privateString remark;//组序列@GroupSequence({Default.class,AddGroup.class,UpdateGroup.class})publicinterfaceGroup{}}

多字段关联效验

场景描述:根据某个字段的值不同,对其他不同的属性进行效验
    occupation字段为1时,说明该用户为学生,学校、入学时间、毕业时间为必填项
    occupation字段为2时,说明该用户为在职员工,公司和职位为必填项

  • 添加效验注解
@GroupSequenceProvider(UsersGroupSequenceProvider.class)@DatapublicclassUsers{privateint occupation;//职业:学生 1 / 职工 2@NotBlank(message="学校不能为空!",groups=StudentGroup.class)privateString school;//学校@NotNull(message="入学时间为必填项!",groups=StudentGroup.class)privateDate admissionTime;//入学时间@NotNull(message="毕业时间为必填项!",groups=StudentGroup.class)privateDate graduationTime;//毕业时间@NotNull(message="公司不能为空!",groups=WorkGroup.class)privateString company;//公司@NotNull(message="职位不能为空!",groups=WorkGroup.class)privateString position;//职位publicinterfaceStudentGroup{}publicinterfaceWorkGroup{}@GroupSequence({Default.class,StudentGroup.class,WorkGroup.class})publicinterfaceGroup{}}
  • 自定义分组序列提供器

实现DefaultGroupSequenceProvider接口,根据当前对象实例的occupation值,动态来决定加载哪些校验组进入默认校验组。

publicclassUsersGroupSequenceProviderimplementsDefaultGroupSequenceProvider<Users>{@OverridepublicList<Class<?>>getValidationGroups(Users users){List<Class<?>> defaultGroupSequence=newArrayList<>();
        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;}}

执行数据效验

/**
 * 统一结果类
 */@DatapublicclassResultCode{privateInteger code;privateString msg;publicResultCode(Integer code,String msg){this.code= code;this.msg= msg;}}

@Valid注解

处理validator异常

validator进行参数效验时,未通过效验会抛出MethodArgumentNotValidException异常,捕获并封装为统一结果类返回给前端。

@RestControllerAdvicepublicclassResultExceptionHandler{@ExceptionHandler(MethodArgumentNotValidException.class)publicResultCodehandleMethodArgumentNotValidException(MethodArgumentNotValidException e){Map<String,String> errors=newHashMap<>();
        e.getBindingResult().getAllErrors().forEach((error)->{
            errors.put(((FieldError)error).getField(),error.getDefaultMessage());});returnnewResultCode(500,errors.values().toString());}}

controller接口处理

使用@Valid注解进行参数效验,不指定具体分组

@RestController@RequestMapping("/users")publicclassUsersController{@PostMapping("checkUsers")publicResultCodecheckUsers(@RequestBody@ValidUsers user){//usersService.save(user);returnResultCode.success();}}

ValidatorUtils工具类

自定义异常及处理

自定义参数效验异常:ParamException

publicclassParamExceptionextendsRuntimeException{privateint code=500;privateString msg;publicParamException(){super();}publicParamException(String msg){super(msg);this.msg= msg;}publicParamException(int code,String msg){super(msg);this.msg= msg;this.code= code;}publicParamException(String msg,Throwable cause){super(msg, cause);this.msg= msg;}publicintgetCode(){return code;}publicStringgetMsg(){return msg;}}

捕获自定义ParamException异常并封装为统一结果类返回给前端。

@RestControllerAdvicepublicclassResultExceptionHandler{@ExceptionHandler(ParamException.class)publicResultCodehandleParamException(ParamException e){returnnewResultCode(e.getCode(),e.getMsg());}}

ValidatorUtils与接口

ValidatorUtils工具类,可以指定分组,或,只执行默认分组的效验

publicclassValidatorUtils{privatestaticValidator validator;static{
        validator=Validation.buildDefaultValidatorFactory().getValidator();}/**
     * 校验对象
     * @param object        待校验对象
     * @throws ParamException  校验不通过,则报ParamException异常
     */publicstaticvoidvalidateEntity(Object object)throwsParamException{Set<ConstraintViolation<Object>> constraintViolations= validator.validate(object,Default.class);if(!constraintViolations.isEmpty()){ConstraintViolation<Object> constraint= constraintViolations.iterator().next();thrownewParamException(constraint.getMessage());}}/**
     * 分组校验对象
     * @param object        待校验对象
     * @param groups        待校验的组
     * @throws ParamException  校验不通过,则报ParamException异常
     */publicstaticvoidvalidateEntity(Object object,Class<?>... groups)throwsParamException{Set<ConstraintViolation<Object>> constraintViolations= validator.validate(object, groups);if(!constraintViolations.isEmpty()){ConstraintViolation<Object> constraint= constraintViolations.iterator().next();thrownewParamException(constraint.getMessageTemplate());}}}

controller接口调用ValidatorUtils方法进行效验,并传参分组

@PostMapping("checkUsersByGroup")publicResultCodecheckUsersByGroup(@RequestBodyUsers user){ValidatorUtils.validateEntity(user,Users.Group.class);//usersService.save(user);returnResultCode.success();}
  • 作者:小妖云汐
  • 原文链接:https://blog.csdn.net/qq_42002006/article/details/121921099
    更新时间:2023-10-17 12:01:40