SpringMVC框架学习—SpringMVC之监听器、过滤器及拦截器对比
1.监听器、过滤器和拦截器对⽐
Servlet
:处理Request请求和Response响应过滤器(Filter)
:对Request请求起到过滤的作⽤,作⽤在Servlet之前,如果配置为/*可以对所有的资源访问(servlet、js/css静态资源等)进⾏过滤处理监听器(Listener)
:实现了javax.servlet.ServletContextListener 接⼝的服务器端组件,它随Web应⽤的启动⽽启动,只初始化⼀次,然后会⼀直运⾏监视,随Web应⽤的停⽌⽽销毁。作⽤⼀
:做⼀些初始化⼯作,web应⽤中spring容器启动ContextLoaderListener作⽤⼆
:监听web中的特定事件,⽐如HttpSession,ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控,⽐如统计在线⼈数,利⽤HttpSessionLisener等。
注意:
Servlet
,过滤器(Filter)
,监听器(Listener)
都是配置在应用中的web.xml中,这三个东西是javaEE规范内的组件,所以还要配置在web.xml中的。
拦截器(Interceptor)
:不是javaEE的规范组件,配置在web.xml中应用不认,所以只能配置在springmvc自己的xml配置文件中,是SpringMVC、Struts等表现层框架⾃⼰的,不会拦截jsp/html/css/image的访问等,只会拦截访问的控制器⽅法(Handler)。在三个地方进行拦截,也就是说可拦截的地方有三处在Handler业务逻辑执⾏之前拦截⼀次
,用的最多,比如权限校验在Handler逻辑执⾏完毕但未跳转⻚⾯之前拦截⼀次
在跳转⻚⾯之后拦截⼀次
2.组件运行过程
3.注意 :框架中什么什么器,让我们去扩展的时候往往就是提供一个父类或者接口让我们继承或实现接口,继承或实现之后有了自己的一个类,再将这个类进行注册就ok了
4. 自定义一个拦截器,实现接口HandlerInterceptor
/**
* 自定义springmvc拦截器
*/
public class MyIntercepter01 implements HandlerInterceptor {
/**
* 会在handler方法业务逻辑执行之前执行
* 往往在这里完成权限校验工作
* @param request
* @param response
* @param handler
* @return 返回值boolean代表是否放行,true代表放行,false代表中止
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyIntercepter01 preHandle......");
return true;
}
/**
* 会在handler方法业务逻辑执行之后尚未跳转页面时执行
* @param request
* @param response
* @param handler
* @param modelAndView 封装了视图和数据,此时尚未跳转页面呢,你可以在这里针对返回的数据和视图信息进行修改
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyIntercepter01 postHandle......");
}
/**
* 页面已经跳转渲染完毕之后执行
* @param request
* @param response
* @param handler
* @param ex 可以在这里捕获异常
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyIntercepter01 afterCompletion......");
}
}
5.自定义一个拦截器的xml配置
<!--<mvc:interceptors>:里面可以配置很多哥拦截器-->
<mvc:interceptors>
<!--注册MyInterceptor01,拦截所有handler,之后执行自定义拦截器里面的内容-->
<bean class="com.lagou.edu.interceptor.MyInterceptor01"/>
<mvc:interceptor>
<!--配置当前拦截器的url拦截规则,**代表当前目录下及其子目录下的所有url-->
<mvc:mapping path="/**"/>
<!--exclude-mapping可以在mapping的基础上排除一些url拦截-->
<mvc:exclude-mapping path="/demo/**"/>
<!--注册MyInterceptor01,拦截部分符合条件的handler,执行自定义拦截器里面的内容-->
<bean class="com.lagou.edu.interceptor.MyInterceptor01"/>
</mvc:interceptor>
</mvc:interceptors>
6.单个拦截器的执⾏流程
在运⾏程序时,拦截器的执⾏是有⼀定顺序的,该顺序与配置⽂件中所定义的拦截器的顺序相关。 单个拦截器,在程序中的执⾏流程如下图所示:
- 程序先执⾏
preHandle()
⽅法,如果该⽅法的返回值为true
,则程序会继续向下执⾏处理器(handle)中的⽅法(执行业务逻辑),这个handle
是由HandlerAdapter
进行调用的,否则将不再向下执⾏。 - 在业务处理器
(即控制器Controller类)
处理完请求后,会执⾏postHandle()
⽅法(第二个拦截器)
,然后会通过DispatcherServlet
进行视图渲染,向客户端返回响应。 - 在
DispatcherServlet
处理完请求后,才会执⾏afterCompletion()
(最后一个拦截时机)⽅法。
7.多个拦截器的执⾏流程
- 多个拦截器(假设有两个拦截器Interceptor1和Interceptor2,并且在配置⽂件中, Interceptor1拦截器配置在前),在程序中的执⾏流程如下图所示:
- 从图可以看出,当有多个拦截器同时⼯作时,它们的
preHandle()⽅法
会按照配置⽂件中拦截器的配置顺序执⾏,⽽它们的postHandle()⽅法
和afterCompletion()⽅法
则会按照配置顺序的反序执⾏。