自定义校验注解+全局异常捕获实现自定义请求属性校验
一、自定义校验注解
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; } }
再次访问接口