1.几种组件介绍
1.1. 监听器Listener
Listener
可以监听 web
服务器中某一个 事件操作,并触发注册的 回调函数。通俗的语言就是在 application
,session
,request
三个对象 创建/消亡 或者 增删改 属性时,自动执行代码的功能组件。
1.2. Servlet
Servlet
是一种运行 服务器端 的 java
应用程序,具有 独立于平台和协议 的特性,并且可以动态的生成 web
页面,它工作在 客户端请求 与 服务器响应 的中间层。
1.3. 过滤器Filter
Filter
对 用户请求 进行 预处理,接着将请求交给 Servlet
进行 处理 并 生成响应,最后 Filter
再对 服务器响应 进行 后处理。Filter
是可以复用的代码片段,常用来转换 HTTP
请求、响应 和 头信息。Filter
不像 Servlet
,它不能产生 响应,而是只 修改 对某一资源的 请求 或者 响应。
1.4. 拦截器Interceptor
类似 面向切面编程 中的 切面 和 通知,我们通过 动态代理 对一个 service()
方法添加 通知 进行功能增强。比如说在方法执行前进行 初始化处理,在方法执行后进行 后置处理。拦截器 的思想和 AOP
类似,区别就是 拦截器 只能对 Controller
的 HTTP
请求进行拦截。
2. 过滤器 VS 拦截器
2.1. 两者的区别
Filter
是基于 函数回调的,而Interceptor
则是基于Java
反射 和 动态代理。Filter
依赖于Servlet
容器,而Interceptor
不依赖于Servlet
容器。Filter
对几乎 所有的请求 起作用,而Interceptor
只对Controller
对请求起作用。
2.2. 执行顺序
对于自定义 Servlet
对请求分发流程:
Filter
过滤请求处理;Servlet
处理请求;Filter
过滤响应处理。
对于自定义 Controller
的请求分发流程:
Filter
过滤请求处理;Interceptor
拦截请求处理;- 对应的
HandlerAdapter
处理请求; Interceptor
拦截响应处理;Interceptor
的最终处理;Filter
过滤响应处理。
Interceptor
Interceptor 介绍
拦截器(Interceptor)同 Filter 过滤器一样,它俩都是面向切面编程——AOP 的具体实现
你可以使用 Interceptor 来执行某些任务,例如在 Controller 处理请求之前编写日志,添加或更新配置……
在 Spring中,当请求发送到 Controller 时,在被Controller处理之前,它必须经过 Interceptors(0或多个)。
Spring Interceptor是一个非常类似于Servlet Filter 的概念 。
Interceptor 作用
- 日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算 PV(Page View)等;
- 权限检查:如登录检测,进入处理器检测是否登录;
- 性能监控:通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间。(反向代理,如 Apache 也可以自动记录)
- 通用行为:读取 Cookie 得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取 Locale、Theme 信息等,只要是多个处理器都需要的即可使用拦截器实现。
配置 Interceptor
拦截器 Interceptor
只对 Handler
生效。Spring MVC
会为 Controller
中的每个 请求方法 实例化为一个 Handler
对象,由 HandlerMapping
对象路由请求到具体的 Handler
,然后由 HandlerAdapter
通过反射进行请求 处理 和 响应,这中间就穿插着 拦截处理。
在Spring MVC中,拦截器和Handler(处理器)是两个不同的概念,但它们之间有着密切的联系。
Handler是用来处理HTTP请求的组件,它通常是一个Controller类的方法。当请求进入Spring MVC框架时,DispatcherServlet会根据请求的URL找到对应的Handler。
拦截器是Spring MVC框架中的一种拦截器组件,它可以在Handler执行前或执行后对请求进行拦截和处理。拦截器是通过实现HandlerInterceptor接口来实现的,它有三个方法:preHandle、postHandle和afterCompletion。
在Spring MVC中,拦截器可以在请求进入Handler之前或请求离开Handler之后对请求进行处理。当一个请求到达DispatcherServlet时,DispatcherServlet会按照配置文件中定义的拦截器顺序依次调用每个拦截器的preHandle方法,在Handler执行前对请求进行拦截处理。当Handler执行完毕后,DispatcherServlet会再次按照相反的顺序依次调用每个拦截器的postHandle方法,在Handler执行后对请求进行处理。最后,DispatcherServlet会按照相反的顺序再次调用每个拦截器的afterCompletion方法,在请求完成后进行处理。
因此,拦截器和Handler是相互关联的,拦截器可以在Handler执行前或执行后对请求进行拦截处理,从而对请求进行增强、修改、记录等操作。
自定义 Interceptor
如果你需要自定义 Interceptor 的话必须实现 org.springframework.web.servlet.HandlerInterceptor
接口或继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter
类,并且需要重写下面下面 3 个方法:
preHandler(HttpServletRequest request, HttpServletResponse response, Object handler)
方法在请求处理之前被调用。该方法在 Interceptor 类中最先执行,用来进行一些前置初始化操作或是对当前请求做预处理,也可以进行一些判断来决定请求是否要继续进行下去。该方法的返回至是 Boolean 类型,当它返回 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;当它返回为 true 时会继续调用下一个 Interceptor 的 preHandle 方法,如果已经是最后一个 Interceptor 的时候就会调用当前请求的 Controller 方法。postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
方法在当前请求处理完成之后,也就是 Controller 方法调用之后执行,但是它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)
方法需要在当前对应的 Interceptor 类的 postHandler 方法返回值为 true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行。此方法主要用来进行资源清理。