前言

小伙伴们应该听说过过滤器、拦截器、切面,印象上都能够起到截断拦截的作用,在做一些业务需求时,不知道如何选择,今天老顾就来介绍一下他们之间的区别。

Filter过滤器

过滤器可以拦截到方法的请求和响应(ServletRequest request, ServletResponse response),并对请求响应做出过滤操作。

过滤器依赖于servlet容器。在实现上,基于函数回调,它可以对几乎所有请求进行过滤,一个过滤器实例只能在容器初始化时调用一次。

使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。话不多说,先上代码再定义两个Controller,一个UserController,一个OrderController虽然Filter过滤器和Controller请求都已经定义了,但现在过滤器是不起作用的。需要把Filter配置一下,有两个方案第一个方案在Filter上面加上@Component

@Component

public class TimeFilter implements Filter

第二个方案配置化注册过滤器第二个方案的特点就是可以细化到过滤哪些规则的URL我们来启动应用时,过滤器被初始化了,init函数被回调

请求http://localhost:9000/order/1

看看控制台的日志输出

请求http://localhost:9000/user/1

控制台日志输出停止应用后,控制台输出Filter随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。

1.启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;2.每一次请求时都只调用方法doFilter()进行处理;3.停止服务器时调用destroy()方法,销毁实例。

我们再来看看doFilter方法

doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

从参数我们看到,filter里面是能够获取到请求的参数和响应的数据;但此方法是无法知道是哪一个Controller类中的哪个方法被执行。还有一点需要注意的是,filter中是没法使用注入的bean的,也就是无法使用@Autowired上面代码注入的值为null。这是为什么呢

其实Spring中,web应用启动的顺序是:listener->filter->servlet,先初始化listener,然后再来就filter的初始化,再接着才到我们的dispathServlet的初始化,因此,当我们需要在filter里注入一个注解的bean时,就会注入失败,因为filter初始化时,注解的bean还没初始化,没法注入。

如果一定你要使用,需要做一些处理,可以私信老顾哦

Interceptor拦截器

依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在一个方法前,调用一个方法,或者在方法后,调用一个方法。在WebMvcConfigurationSupport配置一下执行结果我们发现拦截器中可以获取到Controller对象

preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

object handler就是controller方法对象

HandlerMethod handlerMethod = (HandlerMethod)handler;

handlerMethod.getBean().getClass().getName(); //获取类名

handlerMethod.getMethod().getName(); //获取方法名

但我们发现获取不到方法的参数值,这个是为什么呢?在DispatcherServlet类中,方法 doDispatch(HttpServletRequest request, HttpServletResponse response)applyPreHandle这个方法执行,就是执行的拦截器的preHandler方法,但这个过程中,controller方法没有从request中获取请求参数,组装方法参数;而是在ha.handle这个方法的时候,才会组装参数

虽然没法得到方法的参数,但是可以获得IOC的bean哦。

再说明一点的是postHandler方法

postHandler方法的执行,当controller内部有异常,posthandler方法是不会执行的。

afterCompletion方法,不管controller内部是否有异常,都会执行此方法;此方法还会有个Exception ex这个参数;如果有异常,ex会有异常值;没有异常 此值为null

注意点如果controller内部有异常,但异常被@ControllerAdvice 异常统一捕获的话,ex也会为null

Aspect切片

AOP操作可以对操作进行横向的拦截,最大的优势在于他可以获取执行方法的参数,对方法进行统一的处理。常见使用日志,事务,请求参数安全验证上面的代码中,我们是可以获取方法的参数的虽然切面aop可以拿到方法参数,但拿不到response,request对象。

总结

我们这里来总结一下过滤器、拦截器、Aspect,看看区别如果三者方式同时采用,那他们的执行顺序是什么呢?

filter -> interceptor -> ControllerAdvice -> aspect -> controller

返回值顺序,或异常返回顺序

controller -> aspect -> controllerAdvice -> Interceptor -> Filter

用一个图描述一下执行顺序小伙伴们可以根据自身业务,和上面技术的各自特点,去选择相应的技术。今天老顾就介绍到这里,谢谢!!!

后台回复【4】加入享学课堂粉丝交流群,相亲交友,技术交流

推荐阅读:

Redis 下购物车设计实战

Lambda表达式入门(下篇)

Lambda表达式入门(上篇)

就知道你 “在看”

所有controller interceptor_filter、interceptor、aspect不知如何选择相关推荐

  1. android系统智能手表 开箱,安卓智能手表不知如何选择?先看评测告诉你答案

    原标题:安卓智能手表不知如何选择?先看评测告诉你答案 如今智能手表产品经过了几年的发展之后也日趋成熟,除了iOS平台的Apple Watch之外,在安卓平台也有不少的智能手表产品推出,不过由于更为开放 ...

  2. 所有controller interceptor_阿里二面:filter、interceptor、aspect应如何选择?很多人中招...

    欢迎关注头条号:老顾聊技术 精品原创技术分享,知识的组装工 目录 前言 Filter过滤器 Interceptor拦截器 Aspect切片 总结 前言 小伙伴们应该听说过过滤器.拦截器.切面,印象上都 ...

  3. 期货到底做长线好还是短线好,始终不知如何选择?

    每个投资者都有一套自己习惯的操作方式,其实在期货交易中,无论是长线还是短线,它们的基本交易规则都是一样的.并没有什么特别的地方.都是需要截断亏损,让利润奔跑,需要系统化的交易,需要资金管理. 唯一的不 ...

  4. JAVA拦截器(Interceptor)实现以及原码示例

    JAVA拦截器(Interceptor)实现以及原码示例 概念 SpringMVC中拦截器[interceptor] 一.实现拦截器代码 二.单/多 个拦截器运行 1.单个拦截器 2.多个拦截器 源码 ...

  5. python软件怎么使用-Python快速入门—如何选择使用包管理工具?

    原标题:Python快速入门-如何选择使用包管理工具? 源 | cnblogs文 | 包子 在Python环境中已经有很多成熟的包,可以通过安装这些包来扩展我们的程序. 例如,很多时候Python开发 ...

  6. springmvc静态资源;mvc:default-servlet-handler后Controller失效

    springmvc静态资源;mvc:default-servlet-handler后Controller失效 web.xml配置<url-pattern>/</url-pattern ...

  7. kafka中controller的作用_Kafka 常见问题汇总

    Kafka 如何做到高吞吐.低延迟呢? 这里提下 Kafka 写数据的大致方式:先写操作系统的页缓存(Page Cache),然后由操作系统自行决定何时刷到磁盘. 因此 Kafka 达到高吞吐.低延迟 ...

  8. yii框架源码分析之创建controller

    使用yii框架的url路径一般形如hostname/?r=xxxx/xxxx/xxxx&sdfs=dsfdsf 我们可以看到有时会使用protected目录下的controller,有时会使用 ...

  9. kafka专题:kafka的总控制器Controller、消费者重分配策略等核心设计原理详解

    文章目录 1. Kafka核心总控制器Controller 1.1 核心总控制器Controller的Leader选举 1.2 Partition副本选举Leader机制 2. 消费者消费偏移量off ...

最新文章

  1. 设置vue运行npm run dev时候,项目在浏览器自动打开页面的方法
  2. 你所知道的深度学习发展史及核心节点事件?
  3. JAVA设计模式初探之——装饰者模式
  4. struts中select标签的使用
  5. FFmpeg转码指令(测试通过)
  6. 1一9数字行书写法_EduOffice数字书法教室-书法个性化临摹课件制作
  7. java new的是构造函数_Java构造函数
  8. php中手机端ajax上拉加载更多,jQuery手机网页上拉加载更多
  9. 多线程并发编程之构建自定义同步工具
  10. android ndk问题,Android ndk helloWord 问题集锦
  11. python如何跳出函数_python如何跳出函数
  12. ENVI计算不同轨道号范围中的平均高程
  13. java中mergesort函数怎么用,由mergeSort引发的一些思考
  14. windows7下预览psd
  15. QTreeView 使用 QStandardItemModel
  16. ubuntu系统安装完显卡驱动出现黑屏和登录死循环的解决方法(新增惠普暗夜精灵7-3070显卡解决方法)
  17. anime.js的学习小结
  18. 基于SSM的校园外卖点餐系统
  19. 如果你恨一个人,把他送到北京,那是地狱;如果你爱一个人,也送他送到北京,那是天堂...
  20. 关于美食商城HTML网页设计-----在线美食订餐网站html模板源码30个页面(功能齐全) html+css+javascript网页设计实例 企业网站制作...

热门文章

  1. 【C语言】创建一个函数,判断某一正整数是否为完数,并调用这个函数找出1000以内所有完数...
  2. C#LeetCode刷题之#551-学生出勤纪录 I​​​​​​​(Student Attendance Record I)
  3. 文件从头开始读函数_如何从头开始编写自己的Promisify函数
  4. 可访问性不一致 可访问性低_什么是网站可访问性?
  5. laravel5.5 php7,ubuntu 16.04+nginx+mysql+php7.1+laravel5.5环境
  6. 数字签名加密过程举例
  7. 嫌多(线程/进程)太慢? 嫌Scrapy太麻烦?没事,异步高调走起!——瓜子二手车
  8. Python3中异常处理和try/except,try/finally的用法
  9. 3月份Github上最热门的Python开源项目
  10. 源码分析参考:Connection