spring数据深度校验/自定义校验

@Validated和@Valid校验

@Validated和@Valid配合可以进行对象的深层次校验。

@Valid 作用在方法,字段,构造器和参数上
@Validated 作用在类 方法 和参数上

当我们的接口参数中包含深层次的对象时 如:

BaseInfo时公共对象,字段含有校验的逻辑

@Data
public class BaseInfo{
    @NotEmpty(message="名称不能为空")
    private String name;

    @NotNull(message="年龄不能为空")
    private Integer age;

    @SexValidator  //自定义校验逻辑
    private Integer sex;
    
}

 Person为接口接收对象,属性中包含BaseInfo。

@Data
public class Person{
    //@Vlid表示对bseInfo要进行校验
    @Valid
    private BaserInfo baseInfo;

    @NotEmpty(message="年龄不能为空")
    private String localtion;

}
@RestController
public class testController{

    @PostMappering("/postTest")
    public void postTest(@Validated @RequestBody Person person){
        .......
    }
}

对于接口输入参数的一般属性。使用@Validated就可以验证。但是如果属性是自定义的对象类型。则需要加入@Valid 才能做到深层次的校验。

自定义校验

javax.validation.constraints 中包含了基本的字段校验逻辑。但是有时候我们需要自定义的逻辑。自定义的教育你需要实现ConstraintValidator接口。

public interface ConstraintValidator {

	/**
	 * 初始化方法。
     * 在使用此实例进行验证之前调用此方法
     * 可以不实现
     *   
	 */
	default void initialize(A constraintAnnotation) {
	}

	/**
	 * 验证方法
	 */
	boolean isValid(T value, ConstraintValidatorContext context);
}

依赖:

    
        javax.validation
        validation-api
        2.0.1.Final
   
 

先自定义一个注解:如ListValidator和 EquaValidator:

首先是数组校验:

/**
 * 数组校验注解
 */
@Documented
//执行校验的类(j校验器)
@Constraint(
        validatedBy = {ListValidator.class}
)
//注解的使用场景
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ListValue {
    //默认消息的路径
    String message() default "{com.atguigu.common.validator.ListValue.message}";
    //分组信息
    Class[] groups() default {};
    //负载
    Class[] payload() default {};
    //注解携带的数据
    int[] values() default {};
}


/**
 *自定义数组校验方法
 */
public class ListValidator implements ConstraintValidator {
   private Set set =  new HashSet();
   //初始化方法
	@Override
	public void initialize(ListValue constraintAnnotation) {
		int[] value = constraintAnnotation.values();
		if (value.length>0){
			for (int i : value) {
				set.add(i);
			}
		}

	}
	//校验方法
	@Override
	public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) {
		return set.contains(integer);
	}
}

相等校验:EqualValidtor:

@Documented
@Constraint(validatedBy = {EqualsValidator.class})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface EqualsValue {
 
    String message() default "必须是xzh";

    String value default null;
 
    Class[] groups() default { };
 
    Class[] payload() default { };
}


public class EqualsValidator implements ConstraintValidator {
       
    String defaultValue = null; 

    @Override
    public void initialize(ListValue constraintAnnotation) {
	     value = constraintAnnotation.value();
	}

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if(defaultValue != null && value != null ){
             return defaultValue.equals(value);
        }        
    }
}

之后我们就可以在自己需要校验的属性中配置校验数据了

@Data
public class BaseInfo{
    @NotEmpty(message="名称不能为空")
    private String name;

    @NotNull(message="年龄不能为空")
    private Integer age;

    @SexValidator  //自定义校验逻辑
    private Integer sex;

    @ListValue(values={1, 2, 3}, maessage="数组参数必须是1,2,3")
    private Integer lists;

    @EqualValue(value="123", message="数据必须是123")
    private String equalsValue;
    
}

参数校验不匹配会抛出异常org.springframework.web.bind.MethodArgumentNotValidException。我们可以在自定义的拦截器中拦截即可

你可能感兴趣的:(spring,java,后端)