欢迎访问个人博客 德鲁大叔撸代码 在对外开放接口的时候,我们每次需要对调用者传进来的参数进行校验,对于少量并且参数简单的接口,我们完全可以用最原始的方法进行校验。比如:

public User selectUser(User user) {
        log.info("[查询用户信息],请求参数:{}", JSONUtils.toJSONString(user));
        // 参数校验(性别  用户名  地址  用户状态等)
        if(StringUtils.isNotEmpty(user.getSex()) && StringUtils.isNotEmpty(user.getAddress()) && StringUtils.isNotEmpty(user.getStatu())){
            //当校验通过的时候 执行后面的逻辑
            return user;  // 查询数据库  返回的用户信息
        }else {
            log.info("参数校验未通过,请确认请求参数并重试");
            return null;
        }
    }

但是,当有很多个接口需要对外开放,并且每个接口都有很多的字段,如果还用上面的校验方法的话,显然是不够合理的。那最好的解决办法就是把最常见的参数校验做成一个公共的方法,这样每个接口都不必写重复的校验方法。避免了大量的重复代码。
常见的参数校验主要校验的信息比如:
①空或长度 ②非空且长度 ③空或数字长度 ④非空且数字长度 等等

下面列举出一些常用的参数校验方法:

在此之前,一定要引入:

<dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.6</version>
        </dependency>

部分用到的正则表达式:

private static String REQ_EX_Amt = "^(?!0\\.00)(0|[1-9][0-9]*)[\\.][0-9]{2}$";
    private static Pattern PATTERN_AMT = Pattern.compile(REQ_EX_Amt);

    private final static String NUMERIC_REGEX = "^[0-9]+$";
    private static Pattern PATTERN_NUMERIC = Pattern.compile(NUMERIC_REGEX);

    private final static String NUMERIC_ALPHABET_REGEX = "^[a-zA-Z0-9]+$";
    private static Pattern PATTERN_NUMERIC_ALPHABET = Pattern.compile(NUMERIC_ALPHABET_REGEX);

1、空或长度

public static void checkParamNullOrLength(String param, int length, String paramName, boolean isFixed) {
        if (StringUtils.isEmpty(param)) {
            return;
        } else {
            if (isFixed) {
                checkRequestParam(StringUtils.length(param) == length, String.format("%s长度需为%d位", paramName, length));
            } else {
                checkRequestParam(StringUtils.length(param) <= length, String.format("%s最大长度为%d位", paramName, length));
            }
        }
    }

2、非空且长度

public static void checkParamLength(String param, int length, String paramName, boolean isFixed) {
        checkRequestParam(StringUtils.isNotEmpty(param), String.format("%s为空", paramName));
        if (isFixed) {
            checkRequestParam(StringUtils.length(param) == length, String.format("%s长度需为%d位", paramName, length));
        } else {
            checkRequestParam(StringUtils.length(param) <= length, String.format("%s最大长度为%d位", paramName, length));
        }
    }

3、空或数字长度

public static void checkParamNullOrNumeric(String param, int length, String paramName, boolean isFixed) {
        if (StringUtils.isEmpty(param)) {
            return;
        } else {
            checkParamNumeric(param, length, paramName, isFixed);
        }
    }

4、非空且数字长度

public static void checkParamNumeric(String param, int length, String paramName, boolean isFixed) {
        checkParamLength(param, length, paramName, isFixed);
        Matcher matcherNumeric = PATTERN_NUMERIC.matcher(param);
        if (!matcherNumeric.matches()) {
            throw new BizException(TopqurSubRespEnum.INVALID_PARAMETER.getCode(), String.format("%s需为数字", paramName));
        }
    }

5、空或数字字母长度

public static void checkParamNullOrNumericOrAlphabet(String param, int length, String paramName, boolean isFixed) {
        if (StringUtils.isEmpty(param)) {
            return;
        } else {
            checkParamNumericOrAlphabet(param, length, paramName, isFixed);
        }
    }

6、非空且数字字母长度

public static void checkParamNumericOrAlphabet(String param, int length, String paramName, boolean isFixed) {
        checkParamLength(param, length, paramName, isFixed);
        Matcher matcherNumericAlphabet = PATTERN_NUMERIC_ALPHABET.matcher(param);
        if (!matcherNumericAlphabet.matches()) {
            throw new BizException(TopqurSubRespEnum.INVALID_PARAMETER.getCode(), String.format("%s需为数字字母", paramName));
        }
    }

7、金额校验

public static void checkRequestParamAmt(String name, String amount) {
        Matcher matcherFeeAmt = PATTERN_AMT.matcher(amount);
        if (!matcherFeeAmt.matches()) {
            throw new BizException(TopqurSubRespEnum.INVALID_PARAMETER.getCode(),
                    name + "金额格式不正确");
        }
    }

8、校验多个字段同时为空或不为空

public static final String ALL_NULL = "ALL_NULL";
    public static final String ALL_NOT_NULL = "ALL_NOT_NULL";
    public static final String MIXED = "MIXED";

    public static String checkRequestParamAllNullOrNot(String... value) {
        String type = ALL_NOT_NULL;
        if (StringUtils.isEmpty(value[0])) {
            type = ALL_NULL;
        }
        for (int i = 1; i < value.length; i++) {
            if (ALL_NULL.equals(type) && StringUtils.isNotEmpty(value[i])) {
                return MIXED;
            } else if (ALL_NOT_NULL.equals(type) && StringUtils.isEmpty(value[i])) {
                return MIXED;
            }
        }
        return type;
    }

有了上面的共用校验参数,就可以在代码中像下面代码一样去使用他们进行参数校验了:

@Override
    public void doTask() {
        TransQueryReqBO reqBO = 调用者传入的请求参数();
        checkParamLength(reqBO.getProductId(), 32, "product_id", false);
        checkParamNullOrLength(reqBO.getVersion(), 10, "version", false);
        checkRequestParam(DateUtils.checkDateYYYYMMDD(reqBO.getReqDate()), "req_date格式错误");
        checkParamLength(reqBO.字段1(), 32, "字段名称", false);
        checkParamLength(reqBO.getReqDate(), 8, "req_date", true);

        checkParamNullOrLength(reqBO.getReqSeqId(), 128, "req_seq_id", false);
        checkParamNullOrLength(reqBO.getPartyOrderId(), 64, "party_order_id", false);
        checkParamNullOrLength(reqBO.getOutTransId(), 64, "out_trans_id", false);

        checkRequestParam(!ALL_NULL.equals(checkRequestParamAllNullOrNot(reqBO.getReqSeqId(),
                reqBO.getOutTransId(), reqBO.getPartyOrderId())),
                "req_seq_id、party_order_id、out_trans_id 至少填一");
    }

这样看起来,整个参数校验就整齐干净了很多。