优雅数据校验

463 阅读2分钟

起因

总有一些时候,要对数据校验,要写个方法,很是麻烦,于是写了一个工具类,不爱用Spring Validation,因为我不知道多少个校验规则

理解

个人认为函数和方法是不一样的,函数是函数,方法是方法!按理说函数不应该包含业务,方法可以包含业务,也就是说函数应该是纯函数+尽可能不耦合业务

核心目的

把方法变成了 函数+业务校验参数,参数的重用更高!

代码实现

/**
 * 参数校验
 * <p>
 * Created by songzhaoying on 2021/5/18 09:40.
 *
 * @author songzhaoying@aa.com.
 * @date 2021/5/18 09:40.
 */
public class ValidatorUtil {

    /**
     * null 校验
     */
    public static final Predicate IS_NULL = Objects::isNull;

    /**
     * 空值校验
     */
    public static final Predicate<String> IS_BLANK = StringUtils::isBlank;

    /**
     * 空值校验
     */
    public static final Predicate<Object> IS_EMPTY = ObjectUtils::isEmpty;

    /**
     * 0 校验
     */
    public static final Predicate<BigDecimal> IS_ZERO = o -> {
        if (o == null) {
            return false;
        }
        return BigDecimal.ZERO.compareTo(o) == 0;
    };


    /**
     *
     */
    private ValidatorUtil() {

    }

    /**
     * 数据处理
     *
     * @param bizData      数据
     * @param itemConsumer 处理函数
     * @param <T>
     */
    public static <T> void initData(T bizData, Consumer<? super T> itemConsumer) {
        if (itemConsumer == null) {
            return;
        }
        itemConsumer.accept(bizData);
    }

    /**
     * 校验参数 无null
     *
     * @param failException 失败异常
     * @param objects       校验数据集
     * @return
     * @throws Exception
     */
    public static boolean check0Null(Supplier<? extends RuntimeException> failException
            , Object... objects) throws Exception {
        Predicate[] predicates = {IS_NULL};
        return checkObjects(failException, predicates, objects);
    }

    /**
     * 校验参数 无空
     *
     * @param failException 失败异常
     * @param objects       校验数据集
     * @return
     * @throws Exception
     */
    public static boolean check0Empty(Supplier<? extends RuntimeException> failException
            , Object... objects) throws Exception {
        Predicate[] predicates = {IS_EMPTY};
        return checkObjects(failException, predicates, objects);
    }

    /**
     * 校验参数
     *
     * @param failException  失败异常
     * @param failPredicates 失败规则
     * @param objects        校验数据集
     * @return
     * @throws Exception
     */
    public static boolean checkObjects(Supplier<? extends RuntimeException> failException
            , Predicate[] failPredicates
            , Object... objects) throws Exception {
        boolean ret = true;

        for (Object object : objects) {
            ret = checkFalseException(object, failException, failPredicates);

            if (!ret) {
                break;
            }
        }

        return ret;
    }

    /**
     * 校验参数
     *
     * @param failException  失败异常
     * @param objectList     校验数据集
     * @param failPredicate  失败规则
     *
     * @return
     * @throws Exception
     */
    public static <T> boolean checkList(Supplier<? extends RuntimeException> failException
            , List<T> objectList
            , Predicate<T>... failPredicate) throws Exception {
        boolean ret = true;

        for (T object : objectList) {
            ret = checkFalseException(object, failException, failPredicate);

            if (!ret) {
                break;
            }
        }

        return ret;
    }

    /**
     * 校验
     *
     * @param param          校验数据
     * @param failPredicates 失败规则   如果参数=a 是错误 p -> p == "a" 为真 => 返回false
     * @param <T>
     * @return
     */
    @SafeVarargs
    public static <T> boolean checkFalse(T param, Predicate<T>... failPredicates) {
        if (failPredicates == null) {
            return true;
        }
        for (Predicate<T> predicate : failPredicates) {
            if (predicate == null) {
                continue;
            }
            // 如果错误规则成立 返回 false
            if (predicate.test(param)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 校验 失败异常
     *
     * @param param          校验数据
     * @param failException  失败异常
     * @param failPredicates 失败规则
     * @param <T>
     * @return
     */
    @SafeVarargs
    public static <T> boolean checkFalseException(T param
            , Supplier<? extends RuntimeException> failException
            , Predicate<T>... failPredicates) throws Exception {
        boolean checked = checkFalse(param, failPredicates);

        // 如果错误规则成立
        if (!checked
                && failException != null && failException.get() != null) {
            throw failException.get();
        }

        return checked;
    }

    /**
     * main
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        boolean checkNull = check0Null(null, "null", null);
        System.out.println(checkNull);

        boolean checkNull2Blank = check0Empty(null, "a", "null", BigDecimal.ZERO);
        System.out.println(checkNull2Blank);

        boolean test = ValidatorUtil.checkFalse(" "
                , ValidatorUtil.IS_NULL
                , ValidatorUtil.IS_BLANK
        );
        System.out.println(test);

        String testStr = "a";
        boolean check2Fail = ValidatorUtil.checkFalseException(testStr
                , () -> new RuntimeException("参数校验错误")
                , Objects::isNull
                , p -> {
                    // 等同 p -> p == "a"
                    if ("a".equals(p)) {
                        return true;
                    }
                    return false;
                }
                , s -> {
                    if (s.length() < 2) {
                        throw new RuntimeException("长度小于2");
                    }
                    // 返回 false = 参数无错误
                    return false;
                });
        System.out.println(check2Fail);
    }

}