• Java开发学习(十九)AOP环绕通知案例之密码数据兼容处理


    一、需求分析

    需求: 对百度网盘分享链接输入密码时尾部多输入的空格做兼容处理。

    问题描述:

    • 点击链接,会提示,请输入提取码,如下图所示

    • 当我们从别人发给我们的内容中复制提取码的时候,有时候会多复制到一些空格,直接粘贴到百度的提取码输入框

    • 但是百度那边记录的提取码是没有空格的

    • 这个时候如果不做处理,直接对比的话,就会引发提取码不一致,导致无法访问百度盘上的内容

    • 所以多输入一个空格可能会导致项目的功能无法正常使用。

    • 此时我们就想能不能将输入的参数先帮用户去掉空格再操作呢?

    答案是可以的,我们只需要在业务方法执行之前对所有的输入参数进行格式处理——trim()

    • 是对所有的参数都需要去除空格么?

    也没有必要,一般只需要针对字符串处理即可。

    • 以后涉及到需要去除前后空格的业务可能会有很多,这个去空格的代码是每个业务都写么?

    可以考虑使用AOP来统一处理。

    • AOP有五种通知类型,该使用哪种呢?

    我们的需求是将原始方法的参数处理后在参与原始方法的调用,能做这件事的就只有环绕通知。

    综上所述,我们需要考虑两件事: ①:在业务方法执行之前对所有的输入参数进行格式处理——trim() ②:使用处理后的参数调用原始方法——环绕通知中存在对原始方法的调用

    二、环境准备

    • 创建一个Maven项目

    • pom.xml添加Spring依赖

      <dependencies>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
          </dependency>
          <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
          </dependency>
        </dependencies>
    • 添加ResourcesService,ResourcesServiceImpl,ResourcesDao和ResourcesDaoImpl类

      public interface ResourcesDao {
          boolean readResources(String url, String password);
      }
      @Repository
      public class ResourcesDaoImpl implements ResourcesDao {
          public boolean readResources(String url, String password) {
              //模拟校验
              return password.equals("root");
          }
      }
      public interface ResourcesService {
          public boolean openURL(String url ,String password);
      }
      @Service
      public class ResourcesServiceImpl implements ResourcesService {
          @Autowired
          private ResourcesDao resourcesDao;
      ​
          public boolean openURL(String url, String password) {
              return resourcesDao.readResources(url,password);
          }
      }
      ​
    • 创建Spring的配置类

      @Configuration
      @ComponentScan("com.itheima")
      public class SpringConfig {
      }
    • 编写App运行类

      public class App {
          public static void main(String[] args) {
              ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
              ResourcesService resourcesService = ctx.getBean(ResourcesService.class);
              boolean flag = resourcesService.openURL("http://pan.baidu.com/haha", "root");
              System.out.println(flag);
          }
      }

    最终创建好的项目结构如下:

    现在项目的效果是,当输入密码为"root"控制台打印为true,如果密码改为"root "控制台打印的是false

    需求是使用AOP将参数进行统一处理,不管输入的密码root前后包含多少个空格,最终控制台打印的都是true。

    三、具体实现

    步骤1:开启SpringAOP的注解功能
    @Configuration
    @ComponentScan("com.itheima")
    @EnableAspectJAutoProxy
    public class SpringConfig {
    }
    步骤2:编写通知类
    @Component
    @Aspect
    public class DataAdvice {
        @Pointcut("execution(boolean com.itheima.service.*Service.*(*,*))")
        private void servicePt(){}
        
    }
    步骤3:添加环绕通知
    @Component
    @Aspect
    public class DataAdvice {
        @Pointcut("execution(boolean com.itheima.service.*Service.*(*,*))")
        private void servicePt(){}
        
        @Around("DataAdvice.servicePt()")
        // @Around("servicePt()")这两种写法都对
        public Object trimStr(ProceedingJoinPoint pjp) throws Throwable {
            Object ret = pjp.proceed();
            return ret;
        }
        
    }
    步骤4:完成核心业务,处理参数中的空格
    @Component
    @Aspect
    public class DataAdvice {
        @Pointcut("execution(boolean com.itheima.service.*Service.*(*,*))")
        private void servicePt(){}
        
        @Around("DataAdvice.servicePt()")
        // @Around("servicePt()")这两种写法都对
        public Object trimStr(ProceedingJoinPoint pjp) throws Throwable {
            //获取原始方法的参数
            Object[] args = pjp.getArgs();
            for (int i = 0; i < args.length; i++) {
                //判断参数是不是字符串
                if(args[i].getClass().equals(String.class)){
                    args[i] = args[i].toString().trim();
                }
            }
            //将修改后的参数传入到原始方法的执行中
            Object ret = pjp.proceed(args);
            return ret;
        }
        
    }
    步骤5:运行程序

    不管密码root前后是否加空格,最终控制台打印的都是true

    步骤6:优化测试

    为了能更好的看出AOP已经生效,我们可以修改ResourcesImpl类,在方法中将密码的长度进行打印

    @Repository
    public class ResourcesDaoImpl implements ResourcesDao {
        public boolean readResources(String url, String password) {
            System.out.println(password.length());
            //模拟校验
            return password.equals("root");
        }
    }

    再次运行成功,就可以根据最终打印的长度来看看,字符串的空格有没有被去除掉。

    注意:

     

     

  • 相关阅读:
    06-继承与多态(动手动脑与验证)
    课堂测试四(文件读写)
    字符串加密
    String方法阅读笔记
    03-类与对象(动手动脑)
    计算已经创建了多少个对象
    递归练习(课程作业)
    02-方法(动手动脑)
    猜数字游戏
    JAVA语言实现简单登录界面
  • 原文地址:https://www.cnblogs.com/xiaoyh/p/16412341.html
Copyright © 2020-2023  润新知