除了使用已定义的校验规则外,我们也可以根据自定的业务自定义校验规则,接下来我们介绍一下如何自定义 Hibernate Validator校验规则。
声明自定义注解需要我们
我们这里通过添加用户地区校验逻辑来进行讲解,如果用户是天津 北京 河北的用户就支持其进行用户的新增否则则不支持。
首先我们先创建名称为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 { };
}
下面2行代码是自定义规则注解必须要添加的代码:
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
具体代码如下:
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;
}
还是上面的案例 你有么有发现我们将地区写死到了自定义注解类中,如果我们新增的话还需要修改自定义注解类,下面我们将地区通过注解的参数进行传入方式来限定用户的地区。
具体操作步骤如下:
具体代码如下:
在自定义注解上声明 自定义逻辑处理内部类 的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;
}
像上面河北 天津这样的数据是一般是不会有变化的,我们可以将他们定义成枚举,通过将枚举的值传入自定义规则注解中来进行判断。
和上面自定义规则带参数注解处理方式是一样的,不相同的地方就是我们的注解参数由原来的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;
}
我们可以通过官网地址 查看具体使用教程
另外也可以关注一下 我的GitHub项目: springbootexamples 进行学习