Spring-Boot引入版本依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Controller如何进行参数校验
类上加@Validated注解,方法参数上加@Valid注解,然后使用RestControllerAdvice对异常进行捕获,封装。
Service如何进行参数验证
无interface的情况
和controller的参数验证一样,还是通过@Validated和@Valid注解来实现,异常还是会抛到Controller里面,不过ControllerAdvice捕获的异常类型会有差异,这个自己实战一下就知道了。
有interface的情况
@Valid注解要写在interface的方法上,不能直接写在实现类上
级联验证
针对对象中包含对象,或者List的这两种场景
-
如果是单个对象,直接在外出类对象上加注解@Valid
-
如果是List对象,将@Valid注解写在@Valid List上面,或者List<@Valid People>,这两种写法
分组验证
针对同一个对象,有不同的验证场景,比如针对新增和修改时,对主键id的校验规则不一致
具体做法,参数上配置group分组(可以在类中定义接口,Update,Add),然后controller方法参数上,将@Valid改为spring的@Validated,然后加上指定分组,注意要加上Default分组。
自定义注解
- 定义注解类型
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
validatedBy = {SensitiveCharCheckValidator.class}
)
public @interface SensitiveCharCheck {
String message() default "存在敏感字段";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
- 实现ConstraintValidator接口,泛型为注解类型+参数类型
public class SensitiveCharCheckValidator implements ConstraintValidator<SensitiveCharCheck,String> {
@Override
public void initialize(SensitiveCharCheck sensitiveCharCheck) {
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
// 如果不包含唐,则校验不通过
if (!s.contains("唐")) {
System.out.println(s+" 校验不通过");
return false;
}
return true;
}
}
扩展知识点
- null值不返回给前端:BaseResult使用这个注解
@JsonInclude(JsonInclude.Include.NON_NULL)
- 复合对象的级联验证,需要在内部对象上加注解,@Valid,List对象
- 方法参数是简单的参数,直接使用@NotNull就行,不用写@Valid
- 返回值也是可以做校验的