欢迎访问个人博客 德鲁大叔撸代码 在对外开放接口的时候,我们每次需要对调用者传进来的参数进行校验,对于少量并且参数简单的接口,我们完全可以用最原始的方法进行校验。比如:
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 至少填一");
}
这样看起来,整个参数校验就整齐干净了很多。