自定义Hibernate Validator规则注解

自定义规则注解

除了使用已定义的校验规则外,我们也可以根据自定的业务自定义校验规则,接下来我们介绍一下如何自定义 Hibernate Validator校验规则。

创建自定义规则无参数注解介绍

声明自定义注解需要我们

  1. 先创建自定义注解。
  2. 在自定义注解类上声明@Constraint元注解。
  3. 在@Constraint的属性validatedBy 中指定自定义逻辑处理类的class对象。
  4. 在自定义逻辑处理类中定义校验规则。

1 创建自定义规则的注解

我们这里通过添加用户地区校验逻辑来进行讲解,如果用户是天津 北京 河北的用户就支持其进行用户的新增否则则不支持。

首先我们先创建名称为Addr的注解 具体代码如下:

@Target({ ElementType.FIELD})//修饰的范围是成员变量
@Retention(RetentionPolicy.RUNTIME)//该注解被保留的时间长短 RUNTIME:在运行时有效
@Constraint(validatedBy = MyAddrValidator.class)//指定校验逻辑处理的Class
public @interface Addr {
	String message() default "不支持该地区!";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
}
  • @Target 是注解的元注解 表示修饰的范围 @Target({ ElementType.FIELD}) 表示修饰的是成员变量
  • @Retention 是注解的元注解 表示注解被保留的时间长短
  • @Retention(RetentionPolicy.RUNTIME) 表示在运行时有效
  • @Constraint: Hibernate Validator 定义元注解 指定处理校验规则的类
  • String message(): 必须有的注解属性字段,该字段是用来定义不符合规则错误信息提示用的。

下面2行代码是自定义规则注解必须要添加的代码:

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

2 在自定义逻辑处理类中定义校验规则逻辑

  1. 自定义逻辑处理类 需要实现 ConstraintValidator接口
  2. 重写 ConstraintValidator接口 的**isValid **方法来完成校验规则的处理。

具体代码如下:


public class MyAddrValidator  implements ConstraintValidator<Addr, String>{
	String[] addrArray = new String[]{"北京","河北","天津"};
	@Override
    public void initialize(Addr addr) {
        //启动时执行
    }
	@Override
	public boolean isValid(String value, ConstraintValidatorContext context) {
		for (String addrStr : addrArray) {
			if(addrStr.equals(value)) {
				 return true;
			}
		}
		return false;
	}

}

测试自定义规则无参数注解

User类中新增addr成员变量 然后将我们自定义规则注解声明在该字段上

public class User {
	
	@Addr(message="我们仅支持北京河北天津的用户!")
	private String addr;
}

通过调用addUser 方法来进行测试:
自定义Hibernate Validator规则注解_第1张图片
自定义Hibernate Validator规则注解_第2张图片
自定义Hibernate Validator规则注解_第3张图片
自定义Hibernate Validator规则注解_第4张图片

创建自定义规则有参数注解

还是上面的案例 你有么有发现我们将地区写死到了自定义注解类中,如果我们新增的话还需要修改自定义注解类,下面我们将地区通过注解的参数进行传入方式来限定用户的地区。

具体操作步骤如下:

  1. 通过@Constraint元注解的validatedBy 属性指定我们 自定义逻辑处理内部类 Class对象(这个类在自定义注解中)
  2. 自定义逻辑处理内部类 通过实现ConstraintValidato 接口重写initialize方法来获取到自定义注解中的值。
  3. 自定义逻辑处理内部类 重写 isValid 方法完成校验逻辑处理。

具体代码如下:
在自定义注解上声明 自定义逻辑处理内部类 的Class对象

@Constraint(validatedBy = AddrWithParam.Validator.class)
public @interface AddrWithParam {
	
}

通过实现initialize 方法来接收自定注解传入参数的值。

public @interface AddrWithParam {
	
    public class Validator implements ConstraintValidator<AddrWithParam, String> {
    	String[] valueArray;
    	@Override
        public void initialize(AddrWithParam addrWithParam){
    		valueArray = addrWithParam.value();
        }
    }
}

具体代码如下:

@Target({ ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AddrWithParam.Validator.class)
public @interface AddrWithParam {
	String[] value();
	String message() default "不支持该地区!";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
    public class Validator implements ConstraintValidator<AddrWithParam, String> {
    	String[] valueArray;
    	@Override
        public void initialize(AddrWithParam addrWithParam){
    		valueArray = addrWithParam.value();
        }
		@Override
		public boolean isValid(String value, ConstraintValidatorContext context) {
			for (String addrStr : valueArray) {
				if(addrStr.equals(value)) {
					 return true;
				}
			}
			return false;
		}
       
    }
}

自定义规则有参数注解测试

首先我们先再addr成员变量上声明AddrWithParam 注解 代码如下:

public class User {
    ....
	@AddrWithParam(value = { "北京","河北","天津" })
	private String addr;
}

自定义Hibernate Validator规则注解_第5张图片
自定义Hibernate Validator规则注解_第6张图片
自定义Hibernate Validator规则注解_第7张图片
自定义Hibernate Validator规则注解_第8张图片

创建自定义规则枚举参数注解

像上面河北 天津这样的数据是一般是不会有变化的,我们可以将他们定义成枚举,通过将枚举的值传入自定义规则注解中来进行判断。

和上面自定义规则带参数注解处理方式是一样的,不相同的地方就是我们的注解参数由原来的string数组变成了枚举。示例代码如下:这里为了方便我们就将枚举定义在了注解的内部了。

@Constraint(validatedBy = AddrWithEnum.Validator.class)
public @interface AddrWithEnum {
	public enum AddrEnum{ HEBEI,BEIJING,TIANJING};
    AddrEnum addr() default AddrEnum.BEIJING;
    
    public class Validator implements ConstraintValidator<AddrWithEnum, String> {
         .....
    }
}

具体的代码如下:

@Target({ ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AddrWithEnum.Validator.class)
public @interface AddrWithEnum {
	public enum AddrEnum{ HEBEI,BEIJING,TIANJING};
    AddrEnum addr() default AddrEnum.BEIJING;
    String message() default "不支持该地区!";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
    public class Validator implements ConstraintValidator<AddrWithEnum, String> {
    	
    	AddrEnum addrEnum;
    	@Override
        public void initialize(AddrWithEnum addrWithEnum){
    		addrEnum = addrWithEnum.addr();
        }
		@Override
		public boolean isValid(String value, ConstraintValidatorContext context) {
			System.out.println(value.equals(addrEnum.toString()));
			System.out.println(addrEnum.toString());
			System.out.println(value);
			if(value.equals(addrEnum.toString())) {
				return true;
			}
			return false;
		}
       
    }
}

进行测试:
首先我们先再addr成员变量上声明@AddrWithEnum注解 代码如下:

public class User {
	
	@AddrWithEnum(addr = AddrEnum.BEIJING)
	private String addr;
}

自定义规则枚举参数注解测试

自定义Hibernate Validator规则注解_第9张图片
自定义Hibernate Validator规则注解_第10张图片
自定义Hibernate Validator规则注解_第11张图片

自定义Hibernate Validator规则注解_第12张图片

我们可以通过官网地址 查看具体使用教程

另外也可以关注一下 我的GitHub项目: springbootexamples 进行学习

你可能感兴趣的:(【SpringBoot】)