AOP SpringBoot 使用注解进行参数校验 检查 (支持get和post)

主要是觉得一个实体类加注释太扯淡,是不是我换个方法这个实体类就不能用了?

 最终的使用方式如下:

@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 包的文章

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值