Spring AOP实战开发(一) springmvc参数非空检查

4 篇文章 0 订阅
3 篇文章 0 订阅

          本系列将为大家介绍笔者在开发过程中使用aop的一些功能扩展,有从网上看到的,也有自己想的,如果有相似的代码,敬请海涵。

          本章将介绍如果通过AOP来对请求的参数进行自动的非空检查并返回。相信部分同学的代码中会出现如下的例子:

if (parameters.get("openId") == null || StringUtils.isBlank(parameters.get("openId").toString())) {
    result.setResult(Constant.FAIL);
    result.setMessage("openId 为空,请检查参数");
    logger.info("openId is null");
} else if (parameters.get("type") == null || StringUtils.isBlank(parameters.get("type").toString())) {
    result.setResult(Constant.FAIL);
    result.setMessage("type 为空,请检查参数");
    logger.info("type is null");
} else if (signListByDays.equals(parameters.get("type").toString()) && (parameters.get("days") == null || StringUtils.isBlank(parameters.get("days").toString()))) {
    result.setResult(Constant.FAIL);
    result.setMessage("天数 为空,请检查参数");
    logger.info("days is null");
} 

        又或者是

 

// 检查参数
if (parameters == null || StringUtils.isBlank(parameters.get("openId"))
        || StringUtils.isBlank(parameters.get("plateNumber"))
        || StringUtils.isBlank(parameters.get("frameNumber"))
        || StringUtils.isBlank(parameters.get("engineNumber"))
        || StringUtils.isBlank(parameters.get("registrationDate"))) {
    result.setResult(Constant.FAIL);
    result.setMessage("参数为空,请检查参数");
    logger.info("parameters is null");
    return result;
}

如果又增加了参数怎么办,继续在代码中添加判断,这样代码的侵入性太大,而且冗余度太多。为了解决这个问题。我们可以这么做。请看下面的一个controller 的方法

/**
 * @Author Eric
 * @Description 增加一个商品模板
 * @Date 13:42 2019/1/29
 * @Param [parameters]
 * @return com.bxlsj.pojo.R
 **/
@RequestMapping(method = RequestMethod.POST)
@RequestRequire(require="supplierId,sku,state,name,unit,purchasePrice,storage",parameter = ProductTempletDto.class)
public R addSupplier(@RequestBody ProductTempletDto productTempletDto){
    try {
        productTempletService.save(productTempletDto);
    } catch (Exception e) {
        logger.error("增加商品模板失败,{}", ExceptionUtil.getTrace(e));
        return R.error(e.getMessage());
    }
    return R.ok();
}

添加一个注解@RequestRequire 让aop来统一的帮我们进行非空的判断。

 

第一步:添加一个注解@RequestRequire

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequestRequire {

    /**
     * 请求当前接口所需要的参数,多个以小写的逗号隔开
     * @return
     */
    public String require() default "";

    /**
     *传递参数的对象类型
     */
    public Class<?> parameter() default Object.class;

}

第二步:再增加一个注解@SetPropertyName 这个注解的主要目的是为了非空检查返回属性的中文信息

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SetPropertyName {

    String value() default "";
}

第三步:编写切面类,代码不长就不仔细说了,最后注释掉的部分是可以持续扩展的,目前只检查了null和String类型空字符串的问题,如果还想对数字类型进行大于0等的判定,将注释的部分打开就可以了

/**
 * @author Eric
 * @version 1.0
 * @ClassName: RequestRequireAspect
 * @Description: TODO
 * @company lsj
 * @date 2019/1/30 9:49
 **/
@Component
@Aspect
public class RequestRequireAspect {

    private static final Logger logger = LoggerFactory.getLogger(RequestRequireAspect.class);

    static final String split = ",";

    @Pointcut("@annotation(com.bxlsj.base.annotation.RequestRequire)")
    public void controllerInteceptor() {

    }

    /**
     * controller层增强类,用于检测参数为空的情况
     * @author Eric
     * @date 9:52 2019/1/30
     * @params pjp
     * @throws
     * @return java.lang.Object
     **/
    @Around("controllerInteceptor()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {

        // 获取注解的方法参数列表
        Object[] args = pjp.getArgs();

        // 获取被注解的方法
        MethodInvocationProceedingJoinPoint mjp = (MethodInvocationProceedingJoinPoint) pjp;
        MethodSignature signature = (MethodSignature) mjp.getSignature();
        Method method = signature.getMethod();

        // 获取方法上的注解
        RequestRequire require = method.getAnnotation(RequestRequire.class);

        // 以防万一,将中文的逗号替换成英文的逗号
        String fieldNames=require.require().replace(",", ",");

        // 从参数列表中获取参数对象
        Object parameter=null;
        for(Object pa:args){
            //class相等表示是同一个对象
            if (pa.getClass()==require.parameter() ) {
                parameter=pa;
            }
        }

        // 通过反射去和指定的属性值判断是否非空
        // 获得参数的class
        Class aClass = parameter.getClass();

        // 遍历参数,找到是否为空
        for(String name:fieldNames.split(split)){
            Field declaredField = aClass.getDeclaredField(name);
            String fieldName = declaredField.getName();
            declaredField.setAccessible(true);
            Object fieldObject = declaredField.get(parameter);
            // 获取属性的中文名称
            SetPropertyName spv = declaredField.getAnnotation(SetPropertyName.class);
            if(spv != null && StringUtils.isNotBlank(spv.value())){
                fieldName = spv.value();
            }

            if(fieldObject == null){
                return R.error("参数" + fieldName + "不能为空");
            }
            // 如果type是类类型,则前面包含"class ",后面跟类名
            if (declaredField.getGenericType().toString().equals("class java.lang.String")) {
                if(StringUtils.isBlank((String)fieldObject)){
                    return R.error("参数" + fieldName + "不能为空");
                }
            }
            // 如果是数字类型的
/*           if (declaredField.getGenericType().toString().equals("class java.lang.Integer")
                  || declaredField.getGenericType().toString().equals("class java.lang.Long")
                   || declaredField.getGenericType().toString().equals("class java.lang.Double")
                  || declaredField.getGenericType().toString().equals("class java.lang.Float")) {
                if(fieldObject == null){
                    return R.error("参数" + fieldName + "不能为空");
               }
            } */
        }
        // 如果没有报错,放行
        return pjp.proceed();
    }
}

如果大家有什么疑问,欢迎留言交流

推荐:史上最全的java开发工具类    地址:https://github.com/EricLoveMia/JavaTools

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值