springboot参数校验

springboot参数传递
  • @PathVariable
  • @RequestParam
  • @RequestBody
JSR303

jsr303 : 也称 bean validation 规范,用于java bean 验证的标准API,,他定义了一组注解,可以在javabean 的属性上声明验证规则

JSR: java specification request

常用注解:

  • @NotNull
  • @Size : 定义属性的最小和最大长度
  • @Min
  • @Max
  • @Pattern : 属性值必须匹配正则
  • @Email
  • @Valid : 对嵌套对象或者集合触发验证
springboot中校验注解

在类上打上 @Validated 才会开启校验

校验javabean 也要设置 @Validated ,,javabean中的每一个字段,也需要验证,,字段可能是一个普通字段,也可能是对象,,如果是对象,,使用@Valid 对嵌套对象触发验证

@Valid@Validated 区别: 这两个都可以对javabean 开启验证,,@Valid是java提供的,,@Validated 是spring 对@Valid的扩展,,一般开启验证使用 @Validated,指定嵌套验证使用@Valid

自定义校验注解

自定义一个注解,校验两次输入密码一样:

  • 这个注解需要遵循一定的规范,他有两个模板方法,必须要有
java 复制代码
@Documented // 注解里面的注释加入到文档
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.TYPE})
@Constraint(validatedBy = PasswordValidator.class)  // 指定多个校验类
public @interface PasswordEquals {
 int min() default 3;
 int max() default 6;
 String message() default "password not equal";

 /**
  *  如果要自定义校验  有两个模板方法,必须加上,,规范必须要有这两个东西
  */
 Class<?>[] groups() default {};
 Class<? extends Payload>[] payload() default {};
}
  • 写你自己的验证逻辑,实现ConstraintValidator接口,,这个接口第一个泛型是:你自定义的注解,, 第二个泛型是: 自定义注解要打在什么类型的数据上,,如果打在类上,就是类的类型,如果打在字段上,就是字段的类型
    这里面可以获取注解传入的值,,和javabean传入的值,,在isValid方法中进行比较,返回true,则验证通过
java 复制代码
/**
 * 泛型:
 *      <自定义注解的类型,自定义注解修饰的目标的类型>
 *
 *
 *     如果注解在类上,,修饰的是类
 *     如果注解在字段上,,修饰的是字段 ,,就是字段的类型
 */
public class PasswordValidator implements ConstraintValidator<PasswordEquals, PersonDTO> {

    private int min;
    private int max;

    /**
     * 校验通过 返回true,不通过返回false
     */
    @Override
    public boolean isValid(PersonDTO personDTO, ConstraintValidatorContext context) {
       // 没有考虑密码为空
        String password01 = personDTO.getPassword01();
        String password02 = personDTO.getPassword02();

        return password01.equals(password02);
    }

    /**
     * 获取注解传入的值
     */
    @Override
    public void initialize(PasswordEquals constraintAnnotation) {
        this.min = constraintAnnotation.min();
        this.max = constraintAnnotation.max();
        ConstraintValidator.super.initialize(constraintAnnotation);
    }
}
  • 将自定义的 ContraintValidator 绑定到指定注解上
    一个注解可以绑定多个 ConstraintValidator 指定多个校验类
参数校验的异常
  • ConstraintViolationException
    路径中传递参数报错 ,比如 @PathVarible ,,@RequestParam 传递的路径参数和query参数报错
    这个异常: 系统会自动拼接这些参数的错误,,在异常的message中返回
java 复制代码
 @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public UnifyResponse handleConstraintViolationException(HttpServletRequest request,ConstraintViolationException e){
        System.out.println("e = " + e);
        // 所有的验证
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();

        // 在 异常的 message 中拼接好了,,如果是在自定义异常要定制化显示,,就需要遍历 ConstraintViolation自己拼接
        return new UnifyResponse(10001, e.getMessage(), request.getMethod() + " " + request.getRequestURI());

    }
  • MethodArgumentNotValidException
    在对javabean验证的时候报错,,,多个校验器没有通过会返回一个集合,,需要自己拼接错误信息,所有异常都要处理,,不能只处理一个
java 复制代码
 @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST) // 400 参数错误
    public UnifyResponse handleBeanValidation(HttpServletRequest request,MethodArgumentNotValidException e){
        String uri = request.getRequestURI();
        String method = request.getMethod();
        // 多个校验器都没有通过,,返回集合
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();

        Optional<String> errorMsg = allErrors.stream().map(DefaultMessageSourceResolvable::getDefaultMessage).reduce((a, b) -> (a + "," + b ));
        System.out.println("errormsg = " + errorMsg);


        return new UnifyResponse(10001, errorMsg.orElse(""), method + "  " + uri);
    }
相关推荐
立志成为coding大牛的菜鸟.11 分钟前
力扣1143-最长公共子序列(Java详细题解)
java·算法·leetcode
鱼跃鹰飞12 分钟前
Leetcode面试经典150题-130.被围绕的区域
java·算法·leetcode·面试·职场和发展·深度优先
爱上语文1 小时前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
荆州克莱2 小时前
springcloud整合nacos、sentinal、springcloud-gateway,springboot security、oauth2总结
spring boot·spring·spring cloud·css3·技术
serve the people2 小时前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端
qmx_072 小时前
HTB-Jerry(tomcat war文件、msfvenom)
java·web安全·网络安全·tomcat
为风而战3 小时前
IIS+Ngnix+Tomcat 部署网站 用IIS实现反向代理
java·tomcat
技术无疆5 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
罗政7 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
架构文摘JGWZ8 小时前
Java 23 的12 个新特性!!
java·开发语言·学习