在整个项目中,调用接口都需要对参数进行合法性判断,参数校验是必须的,且到处存在于我们的代码中(例如之前的代码中,在Service层中对接口的参数进行合法性检验),这样就会导致参数校验的代码和我们的业务逻辑代码混合在一起,以后如果业务需要改变的时候,则需要更改相应的参数校验代码,这就违背了:单一性原则、低耦合等设计原则。所以需要将参数校验和业务代码逻辑进行分离。
整个框架支持对Map
以及String
进行参数校验,如果对一个Map进行参数校验,则调用Validator.newMapCheck()
方法:
Map userInfo = ...; // 假设该Map对象保存了要校验的参数
CheckResult result = Validators.newMapCheck() // 获取一个MapCheck对象
.check(userInfo) // 设置我们要检测的对象
.by(userDaoValidator) // 通过DaoValidator校验器进行校验
.result(); // 获取校验的结果
以上代码简要说明:
1. 使用了Java链式的调用方法;
2. 该框架包含了两种校验器:Dao校验器DaoValidator
以及单一参数校验器ParamValidator
;
3. MapCheck
除了能够使用DaoValidator
校验器进行校验之外,还允许使用on()
对Map其中一个参数进行校验,例如
Map userInfo = ...; // 假设该Map对象保存了要校验的参数
CheckResult result = Validators.newMapCheck() // 获取一个MapCheck对象
.check(userInfo) // 设置我们要检测的对象
.on("userName", false, new ParamValidator())
.on("description", true, new DefaultAcceptedValidator())
.result();
其中on()
需要三个参数:paramName
参数名称,nullable
允许为空,paramValidator
单一参数校验器
result()
获取校验结果,返回一个CheckResult
对象,如果result.isAccepted()
返回true则表示校验通过,如果返回false则校验失败,失败的原因可通过getDenyMsg()
获取;校验器主要包含Dao校验器DaoValidator
以及单一参数校验器ParamValidator
,因为我们项目中,绝大部分都是对DAO参数进行校验,所以这里主要介绍Dao校验器的编写。
以下先介绍几个关键类:
- DaoValidator
接口:抽象化Dao校验器,包含Dao校验器的一些通用操作方法;
- BaseDaoValidator
类:Dao校验器的基类,所有Dao校验器需要继承该基类;
- MapCheck
类:对Map进行校验的操作类;
- StringCheck
类:对String进行校验的操作类;
- IParam
接口:抽象化参数
- Param
类:参数表示类,包含参数名name、是否允许为空nullable,对一个的单一参数校验器validator
编写自定义的校验器,步骤:
1. 继承BaseDaoValidator
类,并使用Spring容器进行管理,所以添加@Component
注解,例如
@Component
public class StudentDaoValidator extends UserDaoValidator {}
public IParam STUDENT_ID_NUM = new Param("studentIdNum", false, new ParamValidator() {
@Override
public void check(String value, CheckResult result) {
if (StringUtils.isNullOrEmpty(value)) {
result.setAccepted(false);
result.setDenyMsg("学生学号不允许为空!");
return;
}
if (studentService.checkStudentIdNumExists(value)) { // 需要StudentService对象
result.setAccepted(false);
result.setDenyMsg("该学生学号[" + value + "]已被注册!");
return;
}
}
});
ParamValidator#check()
方法中,value则表示该需要校验的参数值,对于学生学号studentIdNum而言该value就表示学号,所以直接对该value进行判断即可,如果需要调用Service进行协助判断,则可以通过Spring自动装配相应的Service对象;
initParam()
方法,在该方法中将编写的参数全部添加到allParams中@Override
protected void initParam(Map allParams) {
super.initParam(allParams); // 如果继承其他DaoValidator的子类,则需要添加该句
allParams.put(STUDENT_ID_NUM.getName(), STUDENT_ID_NUM);
}
其他说明:所有的参数校验均写在Controller层,业务逻辑在Service实现
因为以后经常需要用到该参数校验框架,所以对于框架的使用,最好阅读一下源码,该部分的所有Java代码均在包com.knowledge_network.support.validator
目录下,代码量并不多。