自定义校验注解+全局异常捕获实现自定义请求属性校验

一、自定义校验注解

1、使用spring校验引入jar包

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.4.2</version>
  </dependency>

2、创建自定义注解

@Target(ElementType.FIELD)用于声明注解使用在什么地方,方法、类或是属性
@Retention(RetentionPolicy.RUNTIME)用于声明注解的生命周期
@Constraint(validatedBy = MyConstructor.class)使用什么类进行校验(使用自己的校验类进行校验)
String message() default "参数超出最大值请重新输入";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
不要漏掉了


@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyConstructor.class)
public @interface maxValidate {
    public int max() default 20;

    String message() default "参数校验不通过,请重新输入";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

3、创建一个类用于实现属性校验

实现ConstraintValidator接口

initialize用于初始化当前属性添加的注解中max的值
isValid用于校验当前属性值时候符合max,是返回true,否返回false
//MyConstrain为自定义校验注解类名
public class MyContrainHadler implements ConstraintValidator<MyConstrain,Object> {
    private int max;
    @Override
    public void initialize(MyConstrain constraintAnnotation) {
        //获取属性上自定义注解的max值
        max = constraintAnnotation.max();
    }

    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        if(null==o)
        {
            return true;
        }
        //o当前校验属性的值
        if (Integer.valueOf(o.toString())<max)
        {
            return true;
        }
        return false;
    }
}

 4、创建一个实体类使用注解校验年龄属性

public class User {
    private int id;
    @MyConstrain(max = 20)
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

5、创建一个Controller层用于测试

@Controller
public class ValidateDemo {
    @RequestMapping(value = "/validate")
    @ResponseBody
    public String validate(@Valid User user){
        System.out.println(user);
        return "访问成功";
    }

}

6、测试

游览器访问http://localhost:8080/validate?age=20

 

 游览器访问http://localhost:8080/validate?age=40 服务器抛出异常

 

因为参数不符合要求请求就返回失败太不友好了,可以使用全局异常捕获处理参数异常

创建一个异常捕获类

使用@ControllerAdvice
@ExceptionHandler(BindException.class)用于捕获何种异常,
可以通过捕获Exception.class来验证,校验失败时返回的是BingException,注意类路径为
org.springframework.validation.BindException,其他类路径的BingException会导致校验异常不能被当前的方法处理。
@ResponseBody可以使用封装好的返回实体类,这里简单使用map
@ResponseStatus(HttpStatus.OK)表示这个请求返回的状态可以使用200成功状态,前端再通过code获取请求返回的自定义状态码
@ControllerAdvice
public class ExceptionConfig {

    @ExceptionHandler(BindException.class)
    @ResponseBody
    public Map<String,Object> validationExceptionHadler(BindException exception)
    {
        Map<String, Object> map = new HashMap<>();
        map.put("code","401");
        map.put("msg","参数异常");
        return map;
    }
}

再次访问接口

 

posted @ 2021-02-26 18:04  行人~  阅读(123)  评论(1编辑  收藏  举报