基于注解的参数校验框架
近期由于工作的需要,写了一个简易的参数校验框架,虽然市场上有common-validator 和hibernate-validator两个开源的,但是有些情景他们是无法满足的,比如参数字段之间的依赖关系,这在项目中是极其常见的。他们仅仅提供了对字段的简单的格式校验。另外这两种校验框架的校验器都是有状态的,这样导致校验的性能不好,对于录入还无所谓,但是批量excel 导入的这种,就非常吃力了。
出于性能和依赖关系校验的需求,改造下工作的校验框架为一个通用的参数校验框架,支持表达式的格式校验,灵活性极好,代码完全复用,思路明了,适合复杂的参数校验场景,希望各位给予指正其中的不足~
下面我贴出来了我写的框架的代码,但是太麻烦搞格式,我也懒的搞,如果有兴趣,可以下载源码看看~
git地址为:https://github.com/wangxinchun/javaframe-validator
先看下这个框架的用法:
逻辑条件 和 逻辑结论的解析和组装
具体的校验器 接口定义(实现略):/** * 校验器 * @author wangxinchun1988@163.com * @date 2013-12-1下午1:08:55 */public interface IValidator {/** * 校验器统一校验接口 * @param rule 校验规则 * @param name 参数名字 * @param params 待校验的参数集合 * @return 返回此验证结果 */public ValidateResult validate(RuleVO validator, Map<String, String> params);}/** * 数字范围校验校验 * * @author xinchun.wang * eg: value = "[2,12]", * value = "(2,12)", * value = "[2,12)" * value = "(2,12)" */public class NumberLimitValidator extends AbstractValidator {@Overridepublic ValidateResult validate(RuleVO validator, Map<String, String> params) {//校验name对应的值不能为空String paramValue = params.get(validator.getProperty());try {String ruleValue = validator.getRule();boolean leftContains = false;boolean rightContains = false;if(ruleValue.startsWith("[")){leftContains = true;}if(ruleValue.endsWith("]")){rightContains = true;}ruleValue = removeRangeFlag(ruleValue);String[] valueArr = ruleValue.split(",");BigDecimal min = new BigDecimal(valueArr[0].trim());BigDecimal max = new BigDecimal(valueArr[1].trim());BigDecimal paramDecimal = new BigDecimal(paramValue);if(leftContains == true && rightContains == true){if(min.compareTo(paramDecimal) <=0 && max.compareTo(paramDecimal) >=0){return ValidateResult.SUCCESS;}else {return ValidateResult.errorInstance(validator.getTip());}}else if(leftContains = true && rightContains == false){if(min.compareTo(paramDecimal) <=0 && max.compareTo(paramDecimal) >0){return ValidateResult.SUCCESS;}else {return ValidateResult.errorInstance(validator.getTip());}}else if(leftContains == false && rightContains == true){if(min.compareTo(paramDecimal) <0 && max.compareTo(paramDecimal) >=0){return ValidateResult.SUCCESS;}else {return ValidateResult.errorInstance(validator.getTip());}}else {if(min.compareTo(paramDecimal) <0 && max.compareTo(paramDecimal) >0){return ValidateResult.SUCCESS;}else {return ValidateResult.errorInstance(validator.getTip());}}} catch (Exception e) {logWarn(e, validator.getProperty(),params.get(validator.getProperty()),validator.getRule(),this.getClass().getName());return ValidateResult.errorInstance(validator.getTip());}}}/** * 验证器工厂 * @author xinchun.wang * */public class ValidatorFactory {/** * 保存通用验证器缓存*/private static final Map<RuleType, IValidator> commonValidatorCacheMap = new HashMap<RuleType, IValidator>();/** * 本地验证器缓存*/private static final ConcurrentHashMap<String, IValidator> localValidatorCacheMap = new ConcurrentHashMap<String, IValidator>();/** * 通用验证器 */private static StringNotEmptyValidator notEmptyValidator = new StringNotEmptyValidator(); private static StringEmptyValidator emptyValidator = new StringEmptyValidator(); private static StringRegxValidator stringRegxValidator = new StringRegxValidator(); private static StringLimitLengthValidator stringLimitLengthValidator = new StringLimitLengthValidator(); /** 格式型验证*/private static DateFormatValidator dateFormatValidator = new DateFormatValidator(); private static NumberFormatValidator numberFormatValidator =new NumberFormatValidator(); private static NumberModValidator numberModValidator = new NumberModValidator(); private static NumberLimitValidator numberLimitValidator = new NumberLimitValidator(); /** 参考型验证*/ private static NumberReferCompareValidator numberReferCompareValidator = new NumberReferCompareValidator(); private static DateReferCompareValidator dateReferCompareValidator = new DateReferCompareValidator(); private static DateCompareNowValidator dateCompareNowValidator = new DateCompareNowValidator(); private static ValuesLimitValidator valuesLimitValidator = new ValuesLimitValidator(); static { /** 通用验证器的注册*/commonValidatorCacheMap.put(RuleType.empty, emptyValidator);commonValidatorCacheMap.put(RuleType.not_empty, notEmptyValidator);commonValidatorCacheMap.put(RuleType.string_regex, stringRegxValidator);commonValidatorCacheMap.put(RuleType.number_format, numberFormatValidator);commonValidatorCacheMap.put(RuleType.date_format, dateFormatValidator);commonValidatorCacheMap.put(RuleType.string_length_limit, stringLimitLengthValidator);commonValidatorCacheMap.put(RuleType.number_value_limit, numberLimitValidator);commonValidatorCacheMap.put(RuleType.number_value_mod, numberModValidator);commonValidatorCacheMap.put(RuleType.number_compare_refer, numberReferCompareValidator);commonValidatorCacheMap.put(RuleType.date_compare_refer, dateReferCompareValidator);commonValidatorCacheMap.put(RuleType.date_compare_now, dateCompareNowValidator);commonValidatorCacheMap.put(RuleType.values_collection_limit, valuesLimitValidator);}public static IValidator getCommonValidator(RuleType ruleName) {return commonValidatorCacheMap.get(ruleName);}/** * 返回本地自定义的验证器 */public static IValidator getLocalValidator(String name){return localValidatorCacheMap.get(name);}/** 注册自定义验证器 */public static void registerLocalValidator(String name,IValidator validator){localValidatorCacheMap.putIfAbsent(name, validator);}}