简易的参数校验框架

简易的参数校验框架V1.0


一、必要性

在整个项目中,调用接口都需要对参数进行合法性判断,参数校验是必须的,且到处存在于我们的代码中(例如之前的代码中,在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单一参数校验器

  1. 校验的最后均需要调用result()获取校验结果,返回一个CheckResult对象,如果result.isAccepted()返回true则表示校验通过,如果返回false则校验失败,失败的原因可通过getDenyMsg()获取;
  2. 链式调用的顺序固定,错误的顺序将可能无法正确地校验;

三、编写自己的校验器

校验器主要包含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 {}
  1. 编写该Dao校验器的参数,例如学生学号studentIdNum:
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对象;

  1. 必须要重写initParam()方法,在该方法中将编写的参数全部添加到allParams中
@Override
protected void initParam(Map allParams) {
    super.initParam(allParams); // 如果继承其他DaoValidator的子类,则需要添加该句
    allParams.put(STUDENT_ID_NUM.getName(), STUDENT_ID_NUM);
}

四、其他

  1. 其他说明:所有的参数校验均写在Controller层,业务逻辑在Service实现

  2. 因为以后经常需要用到该参数校验框架,所以对于框架的使用,最好阅读一下源码,该部分的所有Java代码均在包com.knowledge_network.support.validator目录下,代码量并不多。

你可能感兴趣的:(java,框架,设计)