主要是觉得一个实体类加注释太扯淡,是不是我换个方法这个实体类就不能用了?
最终的使用方式如下:
@CheckParams(bodyNotNull = {"serseqno"})
public ResponseBean<?> checkMReceiptsInfoUpdate(@RequestBody PkiReceiptsInfo pkiReceiptsInfo) {
}
@CheckParams(paramsNotNull = {"ccy"})
public ResponseBean<List<ReceiptsAcctInfoVO>> getFacctNo(@RequestParam("ccy") String ccy) {
}
上实现。
来向参数校验,注解类:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckParams {
//requestParams中不全为空
String[] paramsNotAllNull() default {};
//requestParams中不为空
String[] paramsNotNull() default {};
//requestParams中可以为空,一般可以不使用
String[] paramsCanNull() default {};
//requestBody中不全部为空
String[] bodyNotAllNull() default {};
//requestBody中不能为空
String[] bodyNotNull() default {};
//requestBody中可以为空,一般可以不使用
String[] bodyCanNull() default {};
}
来向参数校验,注解实现
@Aspect
@Slf4j
@Component
@Order(6)
public class CheckParamsAS {
@Pointcut("@annotation(com.common.annotation.CheckParams)")
public void checkParamsCut() {
}
@Around("checkParamsCut()")
public Object checkParams(ProceedingJoinPoint joinPoint) throws Throwable {
ResponseBeanMsg<?> result = new ResponseBeanMsg<>();
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
ParamsCheckStatus checkStatus = new ParamsCheckStatus();
//獲取被標記不能爲空的屬性集合
checkStatus.setParamsNotNull(methodSignature.getMethod().getAnnotation(CheckParams.class).paramsNotNull());
checkStatus.setParamsNotAllNull(methodSignature.getMethod().getAnnotation(CheckParams.class).paramsNotAllNull());
checkStatus.setBodyNotNull(methodSignature.getMethod().getAnnotation(CheckParams.class).bodyNotNull());
checkStatus.setBodyNotAllNull(methodSignature.getMethod().getAnnotation(CheckParams.class).bodyNotAllNull());
//該注解沒有指定參數
if (checkStatus.getParamsNotNull().length == 0 && checkStatus.getParamsNotAllNull().length == 0 && checkStatus.getBodyNotNull().length == 0 && checkStatus.getBodyNotAllNull().length == 0) {
log.error("没有指定参数信息, 注解将被跳过");
return joinPoint.proceed(joinPoint.getArgs());
}
//检查requestParams
CheckParamsAS.checkRequestParams(joinPoint, checkStatus);
//检查requestBody
CheckParamsAS.checkRequestBody(joinPoint, checkStatus);
if (checkStatus.isParamsHasNull()) {
result.error(MsgConstant.REQUEST_PARAMS_ERROR_MSG);
log.error("requestParams " + backStr("请求参数 %s 不能为null", checkStatus.getRequestParamsIsNull()));
return result;
} else if (checkStatus.getParamsNotAllNull().length > 0 && checkStatus.isParamsAllOrNull()) {
result.error(MsgConstant.REQUEST_PARAMS_ERROR_MSG);
log.error("requestParams " + backStr("请求参数 %s 不能全部为null", Arrays.asList(checkStatus.getParamsNotAllNull())));
return result;
} else if (checkStatus.isBodyHasNull()) {
result.error(MsgConstant.REQUEST_PARAMS_ERROR_MSG);
log.error("requestBody " + backStr("请求参数 %s 不能全部为null", Arrays.asList(checkStatus.getParamsNotAllNull())));
return result;
} else if (checkStatus.getBodyNotAllNull().length > 0 && checkStatus.isBodyAllOrNull()) {
result.error(MsgConstant.REQUEST_PARAMS_ERROR_MSG);
log.error("requestBody " + backStr("请求参数 %s 不能全部为null", Arrays.asList(checkStatus.getParamsNotAllNull())));
return result;
} else {
log.info("参数检查通过");
return joinPoint.proceed(joinPoint.getArgs());
}
}
/**
* 检查 get 参数
* @param joinPoint 切面
* @param checkStatus 检查状态
*/
private static void checkRequestParams(ProceedingJoinPoint joinPoint, ParamsCheckStatus checkStatus) {
//此處從requestHead頭中獲取參數,@Param
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
//检查requestParam
Map<String, String[]> paramsHeadMap = request.getParameterMap();
if (null != paramsHeadMap && paramsHeadMap.keySet().size() > 0) {
Optional<Boolean> any = Arrays.stream(checkStatus.getParamsNotNull()).filter(param -> null == paramsHeadMap.get(param) || paramsHeadMap.get(param).length == 0).map(checkStatus::addNullParams).findAny();
checkStatus.setParamsHasNull(any.isPresent());
Optional<String> first = Arrays.stream(checkStatus.getParamsNotAllNull()).filter(param -> null != paramsHeadMap.get(param) && paramsHeadMap.get(param).length > 0).findFirst();
checkStatus.setParamsAllOrNull(!first.isPresent());
} else if (checkStatus.getParamsNotNull().length > 0 || checkStatus.getParamsNotAllNull().length > 0) {
log.error(" 没有找到 @RequestParam 注解的字段");
}
}
/**
* 检查 Post 参数
* @param joinPoint 切面
* @param checkStatus 检查状态
* @throws IllegalAccessException 异常
*/
private static void checkRequestBody(ProceedingJoinPoint joinPoint, ParamsCheckStatus checkStatus) throws IllegalAccessException {
//检查requestBody
Object[] args = joinPoint.getArgs();
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
//参数注解,1维是参数,2维是注解
Annotation[][] annotations = method.getParameterAnnotations();
//是否处理完成
boolean hasDone = false;
//开始处理参数
for (int i = 0; i < annotations.length; i++) {
Object paramsVO = args[i];
//获取注解数组
Annotation[] paramAnn = annotations[i];
//参数为空,直接下一个参数
if (paramsVO == null || paramAnn.length == 0) {
continue;
}
for (Annotation annotation : paramAnn) {
if (annotation.annotationType().equals(RequestBody.class)) {
//从接收封装的对象
Map<String, Object> paramsBodyMap = new HashMap<>();
if (paramsVO instanceof List<?> && ((List<?>) paramsVO).size() > 0) {
log.info("list集合不为空");
return;
}
// 使用Map接收参数
if (paramsVO instanceof Map) {
paramsBodyMap = (Map<String, Object>) paramsVO;
} else {
//使用对象接收参数,获取对象的全部属性
Field[] fields = new Field[0];
for (Class<?> classTemp = paramsVO.getClass(); classTemp != Object.class; classTemp = classTemp.getSuperclass()) {
try {
Field[] fieldsTemp = classTemp.getDeclaredFields();
fields = Arrays.copyOf(fields, fields.length + fieldsTemp.length);
System.arraycopy(fieldsTemp, 0, fields, fields.length - fieldsTemp.length, fieldsTemp.length);
} catch (Exception e) {
//跳过
}
}
for (Field field : fields) {
field.setAccessible(true);
paramsBodyMap.put(field.getName(), field.get(paramsVO));
}
}
//遍历Body集合
for (String paramName : checkStatus.getBodyNotNull()) {
if (RegexUtils.isEmpty(paramsBodyMap.get(paramName))) {
checkStatus.addNullBody(paramName);
checkStatus.setBodyHasNull(true);
}
}
for (String paramName : checkStatus.getBodyNotAllNull()) {
if (!RegexUtils.isEmpty(paramsBodyMap.get(paramName))) {
checkStatus.setBodyAllOrNull(false);
break;
}
}
hasDone = true;
}
}
if (hasDone) {
break;
}
}
}
/**
* 替換參數, 將參數指定為指定格式
* @param str 字符串
* @param arr 集合
* @return 字符串
*/
private static String backStr(String str, List<String> arr) {
String temp = arr.toString();
return String.format(str, temp.substring(1, temp.length() - 1));
}
}
class ParamsCheckStatus {
//requestParams
private String[] paramsNotNull;
private String[] paramsNotAllNull;
private boolean paramsHasNull = false;
private boolean paramsAllOrNull = true;
//requestBody
private String[] bodyNotNull;
private String[] bodyNotAllNull;
private boolean bodyHasNull = false;
private boolean bodyAllOrNull = true;
private List<String> requestParamsIsNull = new ArrayList<>();
private List<String> requestBodyIsNull = new ArrayList<>();
public String[] getParamsNotNull() {
return paramsNotNull;
}
public void setParamsNotNull(String[] paramsNotNull) {
this.paramsNotNull = paramsNotNull;
}
public String[] getParamsNotAllNull() {
return paramsNotAllNull;
}
public void setParamsNotAllNull(String[] paramsNotAllNull) {
this.paramsNotAllNull = paramsNotAllNull;
}
public boolean isParamsHasNull() {
return paramsHasNull;
}
public void setParamsHasNull(boolean paramsHasNull) {
this.paramsHasNull = paramsHasNull;
}
public boolean isParamsAllOrNull() {
return paramsAllOrNull;
}
public void setParamsAllOrNull(boolean paramsAllOrNull) {
this.paramsAllOrNull = paramsAllOrNull;
}
public String[] getBodyNotNull() {
return bodyNotNull;
}
public void setBodyNotNull(String[] bodyNotNull) {
this.bodyNotNull = bodyNotNull;
}
public String[] getBodyNotAllNull() {
return bodyNotAllNull;
}
public void setBodyNotAllNull(String[] bodyNotAllNull) {
this.bodyNotAllNull = bodyNotAllNull;
}
public boolean isBodyHasNull() {
return bodyHasNull;
}
public void setBodyHasNull(boolean bodyHasNull) {
this.bodyHasNull = bodyHasNull;
}
public boolean isBodyAllOrNull() {
return bodyAllOrNull;
}
public void setBodyAllOrNull(boolean bodyAllOrNull) {
this.bodyAllOrNull = bodyAllOrNull;
}
public List<String> getRequestParamsIsNull() {
return requestParamsIsNull;
}
public void setRequestParamsIsNull(List<String> requestParamsIsNull) {
this.requestParamsIsNull = requestParamsIsNull;
}
public boolean addNullParams(String paramsName) {
return requestParamsIsNull.add(paramsName);
}
public List<String> getRequestBodyIsNull() {
return requestBodyIsNull;
}
public void setRequestBodyIsNull(List<String> requestBodyIsNull) {
this.requestBodyIsNull = requestBodyIsNull;
}
public boolean addNullBody(String paramsName) {
return requestBodyIsNull.add(paramsName);
}
}
更多代码在开源项目gitHub上。除了来向校验,还有来向、去向置空等等,支持 requestParam 和 requestBody 在一个方法里同时使用,已经更新到jar包。
<groupId>com.github.engwen</groupId>
<artifactId>owlMagicComment</artifactId>
详情可以看我之前介绍 owlMagicComment jar 包的文章