一、背景
在 Java mvc 分层架构的实际应用中,从视图层到数据访问层,每一层都会对表单参数信息进行校验,如下图所示:
校验方式普遍采用“抽象工具类”+“逻辑if…else判断”的形式。其中,抽象工具类主要封装了业务常用的校验方法,该方法使用正则表达式对参数进行校验,并返回 boolean 类型的返回值;
// 验证输入用户名:只包含数字和小写字母,且不允许为空
public static boolean isUserName(String name) {
if(StringUtils.isBlank(name)){
// 不允许为空
return false;
}
String regEx = "[a-z0-9\\-]+";
Matcher m = Pattern.compile(regEx).matcher(name);
return m.matches();
}
在业务中进行逻辑判断返回值的真伪,从而控制业务流程走向。
// 新增用户(Controller层)
@PostMapping("/add/user")
public MethodResult<String> addUser(User user) {
// 表单参数校验
if(user == null){
return MethodResult.errorResult("用户信息不能为空");
}
// 调用抽象工具类中的校验
if(!Utils.isUserName(user.getName())){
return MethodResult.errorResult("用户名只能包含数字和小写字母且不能为空");
}
//.... 省略剩余校验逻辑 ....
}
这种验证方式有如下弊端:
- 虽然封装了抽象的校验工具类,但是在业务代码中仍然需要采用大量的if…else…编码。
- 若业务校验规则变更,这些散落在业务代码中的校验语句均需要修改,耗时且容易诱发错误。
二、Bean Validation 规范定义
Bean Validation 规范(JSR303规范)提供了对 Java EE 和 Java SE 中的 Java Bean 进行验证的方式。该规范主要使用注解的方式来实现对 Java Bean 的验证功能,从而使验证逻辑从业务代码中分离出来,如下图所示:
Bean Validation 规范倾向于将验证规则直接放到 Java Bean 本身,使用注解的方式进行规则校验,Bean Validation API为我们提供了可拓展的四大接口(Bootstrapping、Validator、ConstraintViolation、MessageInterpolator)以及约束注解。
Hibernate Validator 对 Bean Validation 规范进行了实现,后续示例代码均基于该实现进行,以下是简要版本清单:
spring-boot-starter-parent-2.1.0.RELEASE;
hibernate-validator-6.0