JAVA高效编程九(验证框架)

                  

 

 

 

 

 

 

编程规范的那些常见词

                          

 

 

校验之BV,HV,SV 

                         

 

 

常用约束注解

                       

 

 

初级,中级,高级注解

                                           

 

 

注解实战

/**
* 待验证对象实体类
* 用户信息类
*/
public class UserInfo {

// 登录场景
public interface LoginGroup {}

// 注册场景
public interface RegisterGroup {}

// 组排序场景
@GroupSequence({
LoginGroup.class,
RegisterGroup.class,
Default.class
})
public interface Group {}

/**
* 用户ID
*/
@NotNull(message = "用户ID不能为空",
groups = LoginGroup.class)
private String userId;

/**
* 用户名
* NotEmpty 不会自动去掉前后空格
*/
@NotEmpty(message = "用户名称不能为空")
private String userName;

/**
* 用户密码
* NotBlank 自动去掉字符串前后空格后验证是否为空
*/
@NotBlank(message = "用户密码不能为空")
@Length(min = 6, max = 20,
message = "密码长度不能少于6位,多于20位")
private String passWord;

/**
* 邮箱
*/
@NotNull(message = "邮箱不能为空",
groups = RegisterGroup.class)
@Email(message = "邮箱必须为有效邮箱")
private String email;

/**
* 手机号
*/
@Phone(message = "手机号不是158后头随便")
private String phone;

/**
* 年龄
*/
@Min(value = 18, message = "年龄不能小于18岁")
@Max(value = 60, message = "年龄不能大于60岁")
private Integer age;

/**
* 生日
*/
@Past(message = "生日不能为未来或当前时间点")
private Date birthday;

/**
* 好友列表
*/
@Size(min = 1, message = "不能少于1个好友")
private List<@Valid UserInfo> friends;

}



/**
* 验证测试类
*/
public class ValidationTest {

// 验证器对象
private Validator validator;
// 待验证对象
private UserInfo userInfo;
// 验证结果集合
private Set<ConstraintViolation<UserInfo>> set;
// 验证结果集合
private Set<ConstraintViolation<UserInfoService>> otherSet;

/**
* 初始化操作
*/
@Before
public void init() {
// 初始化验证器
validator = Validation.buildDefaultValidatorFactory()
.getValidator();

// 初始化待验证对象 - 用户信息
userInfo = new UserInfo();
// userInfo.setUserId("zhangxiaoxi");
userInfo.setUserName("张小喜");
userInfo.setPassWord("zhangxiaoxi");
// userInfo.setEmail("zhangxiaoxi@sina.cn");
userInfo.setAge(30);
Calendar calendar = Calendar.getInstance();
calendar.set(2012, 1, 1);
userInfo.setBirthday(calendar.getTime());

userInfo.setPhone("15800000000");

UserInfo friend = new UserInfo();
// friend.setUserId("wangxiaoxi");
friend.setUserName("王小喜");
friend.setPassWord("wangxiaoxi");
// friend.setEmail("wangxiaoxi@sina.cn");
friend.setPhone("15811111111");

userInfo.setFriends(new ArrayList(){{add(friend);}});
}

/**
* 结果打印
*/
@After
public void print() {
set.forEach(item -> {
// 输出验证错误信息
System.out.println(item.getMessage());
});

}

@Test
public void nullValidation() {
// 使用验证器对对象进行验证
set = validator.validate(userInfo);
}

/**
* 级联验证测试方法
*/
@Test
public void graphValidation() {
set = validator.validate(userInfo);
}

/**
* 分组验证测试方法
*/
@Test
public void groupValidation() {
set = validator.validate(userInfo,
UserInfo.RegisterGroup.class,
UserInfo.LoginGroup.class);
}

/**
* 组序列
*/
@Test
public void groupSequenceValidation() {
set = validator.validate(userInfo,
UserInfo.Group.class);
}

/**
* 对方法输入参数进行约束注解校验
*/
@Test
public void paramValidation() throws NoSuchMethodException {
// 获取校验执行器
ExecutableValidator executableValidator =
validator.forExecutables();

// 待验证对象
UserInfoService service = new UserInfoService();
// 待验证方法
Method method = service.getClass()
.getMethod("setUserInfo", UserInfo.class);
// 方法输入参数
Object[] paramObjects = new Object[]{new UserInfo()};

// 对方法的输入参数进行校验
otherSet = executableValidator.validateParameters(
service,
method,
paramObjects);
}


/**
* 对方法返回值进行约束校验
*/
@Test
public void returnValueValidation()
throws NoSuchMethodException,
InvocationTargetException, IllegalAccessException {

// 获取校验执行器
ExecutableValidator executableValidator =
validator.forExecutables();

// 构造要验证的方法对象
UserInfoService service = new UserInfoService();
Method method = service.getClass()
.getMethod("getUserInfo");

// 调用方法得到返回值
Object returnValue = method.invoke(service);

// 校验方法返回值是否符合约束
otherSet = executableValidator.validateReturnValue(
service,
method,
returnValue);
}

/**
* 对构造函数输入参数进行校验
*/
@Test
public void constructorValidation()
throws NoSuchMethodException {

// 获取验证执行器
ExecutableValidator executableValidator =
validator.forExecutables();

// 获取构造函数
Constructor constructor =
UserInfoService.class
.getConstructor(UserInfo.class);
Object[] paramObjects = new Object[]{new UserInfo()};

// 校验构造函数
otherSet = executableValidator
.validateConstructorParameters(
constructor, paramObjects);

}

}




/**
* 用户信息服务类,单元测试方法不能带参数和返回值,用于高级注解验证
*/
public class UserInfoService {

/**
* UserInfo 作为输入参数
* @param userInfo
*/
public void setUserInfo(@Valid UserInfo userInfo) {}

/**
* UserInfo 作为输出参数
* @return
*/
public @Valid UserInfo getUserInfo() {
return new UserInfo();
}

/**
* 默认构造函数
*/
public UserInfoService() {}

/**
* 接收UserInfo作为参数的构造函数
* @param userInfo
*/
public UserInfoService(@Valid UserInfo userInfo) {}

}

自定义手机号验证

                                               

 

 

/**
* 自定义手机号约束注解
*/
@Documented
// 注解的作用目标
@Target({ElementType.FIELD})
// 注解的保留策略
@Retention(RetentionPolicy.RUNTIME)
// 不同之处:与约束注解关联的验证器
@Constraint(validatedBy = PhoneValidator.class)
public @interface Phone {

// 约束注解验证时的输出信息
String message() default "手机号校验错误";

// 约束注解在验证时所属的组别
Class<?>[] groups() default {};

// 约束注解的有效负载
Class<? extends Payload>[] payload() default {};
}



/**
* 自定义手机号约束注解关联验证器
*/
public class PhoneValidator
implements ConstraintValidator<Phone, String> {

/**
* 自定义校验逻辑方法
* @param value
* @param context
* @return
*/
@Override
public boolean isValid(String value,
ConstraintValidatorContext context) {

// 手机号验证规则:158后头随便
String check = "158\\d{8}";
Pattern regex = Pattern.compile(check);

// 空值处理
String phone = Optional.ofNullable(value).orElse("");
Matcher matcher = regex.matcher(phone);

return matcher.matches();
}
}
posted @ 2021-01-18 20:53  红嘴鲤鱼  阅读(223)  评论(0编辑  收藏  举报