一、参数校验的实现
-
以前参数的校验大都通过编码的方式实现,如 Hutool 实现
StrUtil.isNotEmpty(arg); StrUtil.isNotNull(arg); StrUtil.isNotBlank(arg); ……
-
最近认识了新成员 @Validated 和 @Valid
关于两者的区别@Validated是org.springframework.validation.annotation.Validated,支持group分组
@Valid是javax.validation.Valid实际使用时,可以使用两者的嵌套
更多的高阶使用姿势,可参考:https://segmentfault.com/a/1190000022605819?utm_source=tag-newest
二、自定义一个 @Validated 参数注解
- 定义注解
package com.example.validated.validation; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; /** * 自定义身份证校验注解 * * @author miaoxm * @date 2021/12/24 */ @Documented @Target({ElementType.PARAMETER, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = IdentityCardNumberValidator.class) public @interface IdentityCardNumber { String message() default "身份证号码不合法"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
- 注解校验实现
package com.example.validated.validation; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; /** * 真正的校验逻辑 * * @description * 1.必须实现 ConstraintValidator 接口 * 2.实现了 ConstraintValidator 接口后即使不进行 Bean 配置,spring 容器也会将这个类进行 Bean 管理 * 3.可以在实现了 ConstraintValidator 接口的类中依赖注入其他的 Bean * 4.实现了 ConstraintValidator 接口后必须重写 initialize 和 isValid 这两个方法 * - 其中 initialize 方法主要来进行初始化,通常用来获取自定义注解的属性 * - 其中 isValid 方法主要进行校验逻辑,返回true表示校验通过;返回false表示校验失败 * @author miaoxm * @date 2021/12/24 */ public class IdentityCardNumberValidator implements ConstraintValidator<IdentityCardNumber, Object> { @Override public void initialize(IdentityCardNumber constraintAnnotation) { ConstraintValidator.super.initialize(constraintAnnotation); } @Override public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) { return check(o.toString()); } private boolean check(String arg) { // 具体的参数校验实现可以写在这儿 return true; } }
三、全局异常处理
作用:让校验生效,即参数校验时如果不合法就会抛出异常,我们就可以在全局异常中捕获拦截到,然后进行逻辑处理之后再返回
@RestControllerAdvice
public class MyGlobalExceptionHandler {
……
}