前言

项目中我们经常需要对RESTful api进行拦截,主流实现方法有filter、interceptor、aop,先说一下他们各自的实现。

Filter

AnimalFilter实现javax.servlet.Filter,项目启动时已初始化完成,可在控制台看到打印的初始化日志。

@Component
    public class AnimalFilter implements Filter {
     
        private Logger logger = LoggerFactory.getLogger(getClass());
     
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            logger.info("animalFilter 初始化。。。");
        }
     
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            logger.info("animalFilter doFilter 。。。");
            chain.doFilter(request,response);//过滤器将请求往下传递
        }
     
        @Override
        public void destroy() {
            logger.info("animalFilter 销毁。。。");
        }
    }

如何调用不被component修饰的filter,将上文中的component注解去除,通过下文方式,让注解生效并设置注解生效的url请求地址信息。

@Configuration
    public class AnimalWebConfig {
     
        @Bean
        public FilterRegistrationBean animalFilter(){
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
            AnimalFilter animalFilter = new AnimalFilter();
            filterRegistrationBean.setFilter(animalFilter);
            List<String> urlPattern = new ArrayList<>();
            urlPattern.add("/animal/getAnimalById/*");
            filterRegistrationBean.setUrlPatterns(urlPattern);
            return filterRegistrationBean;
        }
     
    }

由于filter获取的参数为ServletRequest request, ServletResponse response, FilterChain chain,无法知道是哪个类的那个方法调用,更无法知道调用时的参数。

Interceptor

首先编写一个AnimalInterceptor实现HandlerInteceptor方法,实现相应的三个方法,preHandle执行方法前执行返回的结果决定是否往下执行,postHandle当方法返回值时执行,afterCompletion无论成功或失败都将执行,前提是preHandler要返回true。

@Component
    public class AnimalInterceptor implements HandlerInterceptor {
     
        private Logger logger = LoggerFactory.getLogger(getClass());
     
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            String methodName = handlerMethod.getMethod().getName();
            logger.info("AnimalInterceptor:preHandle:methodName:" + methodName);
            logger.info("AnimalInterceptor:preHandle");
            return true;
        }
     
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            logger.info("AnimalInterceptor:preHandle:methodName:" + handlerMethod.getMethod().getName());
            logger.info("AnimalInterceptor:postHandle");
        }
     
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            logger.info("AnimalInterceptor:afterCompletion");
        }
    }

将写好的AnimalInterceptor注入到spring的interceptor注册中心即可

@Component
    public class InterceptorConfig extends WebMvcConfigurerAdapter{
     
        @Autowired
        AnimalInterceptor animalInterceptor;
     
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(animalInterceptor);
        }
    }

虽然interceptor可以知道调用的controller,调用的方法,但获取不到调用方法的参数。

AOP

编写AnimalAspect如下,可将传递的参数打印出来,aop拦截规则设置请查看,https://blog.csdn.net/FU250/article/details/80219415

@Aspect
    @Component
    public class AnimalAspect {
        private Logger logger = LoggerFactory.getLogger(getClass());
     
        @Around("execution(* com.imooc.security.demo.web.controller..*.*(..))")
        public Object handleAnimalController(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            Arrays.stream(proceedingJoinPoint.getArgs()).forEach(arg -> {
                logger.info("arg:"+arg);
            });
            logger.info("AnimalAspect");
            return proceedingJoinPoint.proceed();
        }
    }

三个拦截器的比较如下,根据自己的业务功能需求选择最合适的拦截器。


   

Spring 梳理 - filter、interceptor、aop实现与区别 -第一篇的更多相关文章

  1. spring boot: filter/interceptor/aop在获取request/method参数上的区别(spring boot 2.3.1)

    一,filter/interceptor/aop在获取参数上有什么区别? 1,filter可以修改HttpServletRequest的参数(doFilter方法的功能), interceptor/a ...

  2. Spring 梳理 - filter、interceptor、aop实现与区别 -第二篇

    spring mvc中的Interceptor可以理解为是Spring MVC框架对AOP的一种实现方式.一般简单的功能又是通用的,每个请求都要去处理的,比如判断token是否失效可以使用spring ...

  3. Filter ,Interceptor,AOP

    一.Filter: Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...

  4. Spring整合AspectJ的AOP

    学而时习之,不亦说乎!                              --<论语> 看这一篇之前最好先看前面关于AOP的两篇. http://www.cnblogs.com/z ...

  5. Spring框架IOC和AOP介绍

    说明:本文部分内容参考其他优秀博客后结合自己实战例子改编如下 Spring框架是个轻量级的Java EE框架.所谓轻量级,是指不依赖于容器就能运行的.Struts.Hibernate也是轻量级的. 轻 ...

  6. Spring切面编程之AOP

    AOP 是OOP 的延续,是Aspect Oriented Programming 的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种 ...

  7. Spring的IOC和AOP之深剖

    今天,既然讲到了Spring 的IOC和AOP,我们就必须要知道 Spring主要是两件事: 1.开发Bean:2.配置Bean.对于Spring框架来说,它要做的,就是根据配置文件来创建bean实例 ...

  8. Spring(6)—— AOP

    AOP(Aspect-OrientedProgramming)面向切面编程,与OOP完全不同,使用AOP编程系统被分为切面或关注点,而不是OOP中的对象. AOP的引入 在OOP面向对象的使用中,无可 ...

  9. spring+mybatis利用interceptor(plugin)兑现数据库读写分离

    使用spring的动态路由实现数据库负载均衡 系统中存在的多台服务器是"地位相当"的,不过,同一时间他们都处于活动(Active)状态,处于负载均衡等因素考虑,数据访问请求需要在这 ...

随机推荐

  1. unity之单例模式

    Unity中常见的四种单例 点击进入

  2. 使用css实现水平垂直居中

    1.通过absolute和margin实现(适用于弹窗,具体位置随浏览器屏幕大小变化改变)这种方式需要居中元素的父级必须采用绝对定位或相对定位,被居中元素的尺寸需要固定. <div class= ...

  3. 模板列传值到子窗体中,子窗体中多选gridview中checkbox保存数据多项到数据库中

    <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> &l ...

  4. 设置VS2015背景图片(转载)

    设置方法很简单:安装扩展ClaudiaIDE 1.在这里下载扩展,https://visualstudiogallery.msdn.microsoft.com/9ba50f8d-f30c-4e33-a ...

  5. 问题.spring源码转换为eclipse遇到的问题

    1.下载spring源码 2.下载安装gradle,配置环境变量 3.在spring子项目下执行命令:gradle cleanidea eclipse,会生成对应的.project及.classpat ...

  6. CodeForces-38B-Chess枚举+思维

    CodeForces-38B-Chess 这是一道与下象棋有关的题目,题意是给你一个车和马的坐标,然后再给你一个马,让你判断最后三者都不会被吃掉的可能性,注意的是三者是三个独立的个体. 这道题要知道一 ...

  7. hdu3746(kmp最小循环节)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746 题意:问在一个字符串末尾加上多少个字符能使得这的字符串首尾相连后能够循环 题解:就是利用next ...

  8. CodeForces 917A The Monster 贪心+思维

    As Will is stuck in the Upside Down, he can still communicate with his mom, Joyce, through the Chris ...

  9. 你知道@RequestMapping的name属性有什么用吗?【享学Spring MVC】

    每篇一句 牛逼架构师:把复杂问题简单化,把简单问题搞没 菜逼架构师:把简单问题复杂化 前言 不知这个标题能否勾起你的好奇心和求知欲?在Spring MVC的使用中,若我说@RequestMapping ...

  10. 树莓派的Respbian或者ubuntu系统下安装opencv最有效的方法

    第一种方法当然首选和其他安装包相同的方法pip install opencv-python安装失败后果断选择第二种方法,这第二种方法尝试过很多次了,屡试不爽 第二种方法:sudo apt-get in ...