自定义参数校验注解

校验选项中不允许存在相同的数据


@Target({ FIELD })
@Retention(RUNTIME)
@Documented
@Constraint(
        // 自定义校验器 校验集合中重复的元素
        validatedBy = {DuplicatedElementValidation.class}
)
public @interface NotDuplicatedElement {

    String message() default "{not_duplicated_element_message}";

  //该属性用与校验String数据大小写敏感问题
    boolean ignoreCase() default false;

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

public class DuplicatedElementValidation implements ConstraintValidator<NotDuplicatedElement, Collection<?>> {

    private boolean ignoreCase = false;
    @Override
    public void initialize(NotDuplicatedElement constraintAnnotation) {
      //实现该方法是为了获取注解中定义的参数数据
        ignoreCase = constraintAnnotation.ignoreCase();
    }
    @Override
    public boolean isValid(Collection<?> value, ConstraintValidatorContext context) {

      //此处是校验的开始
        if (CollectionUtils.isEmpty(value)) {
            return true;
        }
        Object obj = value.iterator().next();
        if (obj instanceof String) {
            if (ignoreCase) {
                value = value.stream().map(v -> StringUtils.lowerCase((String) v)).collect(Collectors.toList());
            }
        }
        Set set = new HashSet<>(value);
        return set.size() == value.size();
    }
}

ValidationMessages.properties应该放在resource目录下以message打头的方式
message.not_duplicated_element_message=不允许重复的元素

Note:

对于嵌套对象中加校验注解的,需要在嵌套对象加上@Valid注解,这样加在嵌套对象中的校验注解才会生效。

1.group的作用用于分组校验

@Null(groups = AAAA.class)
@NotNull(groups = BBBB.class)

public String get1(@RequestBody @Validated(value = {AAAA.class, BBBB.class}) ValiationDto valiationDto){
        return "Hello World";
    }

public String get2(@RequestBody @Validated(value = {BBBB.class}) ValiationDto valiationDto){
        return "Hello World";
    }

get1方法会校验@Null和@NotNull
get2方法只会校验@NotNull

2.Payload的作用:可用于校验错误级别,类似日志的级别一样。