自定义注解实现密码的校验以及参数错误的全局异常处理

自定义注解实现密码的校验以及参数错误的全局异常处理

  • 编写自定义注解

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    // 注解的作用目标,ElementType.TYPE表示只能作用在类上
    @Target(ElementType.TYPE)
    // 注解校验的关联类
    @Constraint(validatedBy = PasswordValidator.class)
    public @interface PasswordEqual {
    
        // 注解中不能使用包装类型
        int min() default 4;
    
        int max() default 24;
    
        String message() default "passwords are not equal";
    
        // groups和payload方法是注解中必须要有的两个方法
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    }
    
  • 编写自定义注解的关联类

    /**
     * ConstraintValidator泛型中的第一个参数是关联的注解,第二个参数是注解修饰的目标的类型
     */
    public class PasswordValidator implements ConstraintValidator<PasswordEqual, PersonDTO> {
    
        private int max;
    
        private int min;
    
        /**
         * 初始化方法
         * @param constraintAnnotation
         */
        @Override
        public void initialize(PasswordEqual constraintAnnotation) {
    
            this.min = constraintAnnotation.min();
            this.max = constraintAnnotation.max();
        }
    
        /**
         * 校验的方法
         * @param personDTO
         * @param constraintValidatorContext
         * @return
         */
        @Override
        public boolean isValid(PersonDTO personDTO, ConstraintValidatorContext constraintValidatorContext) {
            if(personDTO == null) {
                return false;
            }
            String password1 = personDTO.getPassword1();
            String password2 = personDTO.getPassword2();
            if(password1==null) {
                this.setErrorMessage(constraintValidatorContext, "密码不能为空");
                return false;
            }
            if(password1.length()<min || password1.length()>max) {
                this.setErrorMessage(constraintValidatorContext, "密码的长度不能少于"+this.min+"个字符, 不能超过"+this.max+"个字符");
                return false;
            }
            boolean match = password1.equals(password2);
            if(!match) {
                this.setErrorMessage(constraintValidatorContext, "两次输入的密码不一致");
            }
    
            return match;
        }
    
        // 设置校验失败的提示消息
        private void setErrorMessage(ConstraintValidatorContext constraintValidatorContext, String errorMessage) {
            constraintValidatorContext.disableDefaultConstraintViolation();
            constraintValidatorContext
                    .buildConstraintViolationWithTemplate(errorMessage)
                    .addConstraintViolation();
        }
    }
    
  • 编写实体类

    @PasswordEqual
    public class PersonDTO {
    
        private String password1;
    
        private String password2;
    
        public String getPassword1() {
            return password1;
        }
    
        public void setPassword1(String password1) {
            this.password1 = password1;
        }
    
        public String getPassword2() {
            return password2;
        }
    
        public void setPassword2(String password2) {
            this.password2 = password2;
        }
    }
    
  • 在控制器中使用

    @RestController
    @RequestMapping(value = "/hello")
    public class HelloWorldController {
    
        @GetMapping(value = "/say")
        public String say(@Validated PersonDTO personDTO) {
    
            return "hello, world";
        }
    }
    
  • 参数错误的全局异常处理

    @ControllerAdvice
    @RestController
    public class GlobalException {
    
        /**
         * 参数校验失败的全局异常处理
         * @param e
         * @return
         */
        // 自定义request状态码
        @ResponseStatus(value = HttpStatus.BAD_REQUEST)
        @ExceptionHandler(value = {BindException.class})
        public Map<String, String> handlerArgsBindException(BindException e) {
            List<ObjectError> errors = e.getAllErrors();
            Map<String, String> map = new HashMap<>();
            errors.forEach(error -> map.put(error.getObjectName(), error.getDefaultMessage()));
            return map;
        }
    }
    
    

    handlerArgsBindException只捕获了通过URL传参而产生的异常,对于RequestBody传参和PathValiable产生的异常没有做处理,可以再定义两个异常捕获的方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值