一般我们对前端传输的参数做校验时,可能都是以以下方式进行,如果再加上字段的长度、正则等校验的话就会显得代码很累赘。

// 新增/修改通用参数非空校验
if (StringUtil.isBlank(menu.getParentId())) {
  throw new LsException(ResultEnum.PARAM_MISSING_ERROR, "父级菜单ID不能为空!");
}
if (StringUtil.isBlank(menu.getMenuName())) {
  throw new LsException(ResultEnum.PARAM_MISSING_ERROR, "菜单名称不能为空!");
}
if (StringUtil.isBlank(menu.getMenuName())) {
  throw new LsException(ResultEnum.PARAM_MISSING_ERROR, "菜单类型不能为空!");
}
/**>>>>>>>>>>>>>>>>>>>>>>>>枚举类字段校验开始<<<<<<<<<<<<<<<<<<<<<<<<<**/
// 校验菜单类型是否存在
if (Objects.nonNull(model.getMenuType())) {
  MenuEnum.MenuType menuType = MenuEnum.MenuType.getByType(model.getMenuType());
  if (Objects.isNull(menuType)) {
    throw new LsException(ResultEnum.PARAM_CHECKED_ERROR, "此菜单类型不存在!");
  }
}
// 校验打开方式是否存在
if (Objects.nonNull(model.getTarget())) {
  MenuEnum.Target target = MenuEnum.Target.getByTarget(model.getTarget());
  if (Objects.isNull(target)) {
    throw new LsException(ResultEnum.PARAM_CHECKED_ERROR, "此打开方式不存在!");
  }
}
// 校验菜单状态是否存在
if (Objects.nonNull(model.getVisible())) {
  MenuEnum.Visible visible = MenuEnum.Visible.getByVisible(model.getVisible());
  if (Objects.isNull(visible)) {
    throw new LsException(ResultEnum.PARAM_CHECKED_ERROR, "此菜单状态不存在!");
  }
}
/**>>>>>>>>>>>>>>>>>>>>>>>>枚举类字段校验结束<<<<<<<<<<<<<<<<<<<<<<<<<**/

 改进方案,使用Hibernate Validator嵌入式注解处理器(概念可参考《深入理解Java虚拟机》——周志明第10.4节)进行表单验证:

1、表单验证工具类ModelValidator

/**
 * 软件版权:流沙~~
 * 修改日期   修改人员     修改说明
 * =========  ===========  =====================
 * 2019/9/30    liusha   新增
 * =========  ===========  =====================
 */
package com.sand.common.util.validator;

import com.sand.common.enums.CodeEnum;
import com.sand.common.exception.BusinessException;
import com.sand.common.util.lang3.StringUtil;
import com.sand.common.util.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 功能说明:表单验证器
 * 开发人员:@author liusha
 * 开发日期:2019/9/30 13:57
 * 功能描述:表单校验,验证非空、长度、正则等等
 */
@Slf4j
public class ModelValidator {
  /**
   * 校验失败条数key值
   */
  public static final String CHECKED_FAIL_NUM = "checkedFailNum";
  /**
   * 校验失败原因key值
   */
  public static final String CHECKED_FAIL_MSG = "checkedFailMsg";
  /**
   * 校验通过的数据列表key值
   */
  public static final String CHECKED_ENTITY_LIST = "checkedEntityList";

  /**
   * 表单验证(对应实体类配置注解)
   *
   * @param entity 校验对象
   * @param <T>
   */
  public static <T extends Object> void checkModel(T entity) {
    checkModel(entity, null);
  }

  /**
   * 表单验证指定字段(对应实体类配置注解)
   *
   * @param entity 校验对象
   * @param <T>
   */
  public static <T extends Object> void checkModel(T entity, String fieldName) {
    try {
      Set<ConstraintViolation<T>> violationSet;
      if (StringUtil.isNotBlank(fieldName)) {
        violationSet = SpringUtil.getBean(Validator.class).validateProperty(entity, fieldName);
      } else {
        violationSet = SpringUtil.getBean(Validator.class).validate(entity);
      }
      if (violationSet.size() > 0) {
        String msg = violationSet.iterator().next().getMessage();
        if (StringUtil.isBlank(msg)) {
          msg = "请求参数有误";
        }
        throw new BusinessException(CodeEnum.PARAM_CHECKED_ERROR, msg);
      }
    } catch (Exception e) {
      log.error("表单验证出错,", e);
      String errorMsg = (e instanceof BusinessException) ? e.getMessage() : "表单验证出错";
      throw new BusinessException(CodeEnum.PARAM_CHECKED_ERROR, errorMsg);
    }
  }

  /**
   * 批量表单验证(对应实体类配置注解)
   *
   * @param entityList 校验对象列表
   * @param <T>
   * @return 校验结果
   */
  public static <T extends Object> Map<String, Object> checkModelList(List<T> entityList) {
    // 校验失败条数
    int checkedFailNum = 0;
    // 校验失败原因
    StringBuilder checkedFailMsg = new StringBuilder();
    // 校验通过的数据列表
    List<T> checkedEntityList = new ArrayList<>();
    for (int i = 0; i < entityList.size(); i++) {
      try {
        checkModel(entityList.get(i));
      } catch (Exception e) {
        checkedFailNum++;
        checkedFailMsg.append("第" + (i + 1) + "条数据:" + e.getMessage() + ";");
        continue;
      }
      checkedEntityList.add(entityList.get(i));
    }
    Map<String, Object> checkedMap = new HashMap<>();
    checkedMap.put(CHECKED_FAIL_NUM, checkedFailNum);
    checkedMap.put(CHECKED_FAIL_MSG, checkedFailMsg);
    checkedMap.put(CHECKED_ENTITY_LIST, checkedEntityList);
    return checkedMap;
  }
}
View Code

相关文章: