今天学习和认识了一下,过滤器和SpringMVC的拦截器的区别,学到了不少的东西,以前一直以为拦截器就是过滤器实现的,现在想想还真是一种错误啊,而且看的比较粗浅,没有一个全局而又细致的认识,由于已至深夜,时间原因,我就把一些网友的观点重点摘录下来,大家仔细看后也一定会有一个比较新的认识(在此非常感谢那些大牛们的无私奉献,分享他们的经验与心得,才能让像我这样的小白有机会站一下你们这些巨人的肩膀,才能少走些弯路)。

  过滤器和拦截器的区别:

  ①拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
  ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

  ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

  写了点测试代码,顺便整理一下思路,搞清楚这几者之间的顺序:

  1.过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。

 
    @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("before...");
chain.doFilter(request, response);
System.out.println("after...");
}
 

  chain.doFilter(request, response);这个方法的调用作为分水岭。事实上调用Servlet的doService()方法是在chain.doFilter(request, response);这个方法中进行的。

  2.拦截器是被包裹在过滤器之中的。

 
    @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
} @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
 

  a.preHandle()这个方法是在过滤器的chain.doFilter(request, response)方法的前一步执行,也就是在 [System.out.println("before...")][chain.doFilter(request, response)]之间执行。

  b.preHandle()方法之后,在return ModelAndView之前进行,可以操控Controller的ModelAndView内容。

  c.afterCompletion()方法是在过滤器返回给前端前一步执行,也就是在[chain.doFilter(request, response)][System.out.println("after...")]之间执行。

  3.SpringMVC的机制是由同一个Servlet来分发请求给不同的Controller,其实这一步是在Servlet的service()方法中执行的。所以过滤器、拦截器、service()方法,dispatc()方法的执行顺序应该是这样的,大致画了个图:其实非常好测试,自己写一个过滤器,一个拦截器,然后在这些方法中都加个断点,一路F8下去就得出了结论。

  

 我自己写的过滤器和拦截器的方法生成的日志
2016-10-27 19:25:59,205 INFO [com.eshore.ismp.adminweb.filter.interceptor.PermissionInterceptor:39] - url0:http://localhost:8080
2016-10-27 19:25:59,205 INFO [com.eshore.ismp.adminweb.filter.interceptor.PermissionInterceptor:43] - requestUri:/adminweb/user_login.do
2016-10-27 19:25:59,206 INFO [com.eshore.ismp.adminweb.filter.interceptor.PermissionInterceptor:44] - contextPath:/adminweb
2016-10-27 19:25:59,206 INFO [com.eshore.ismp.adminweb.filter.interceptor.PermissionInterceptor:45] - url:/user_login.do
2016-10-27 19:25:59,206 INFO [com.eshore.ismp.adminweb.filter.interceptor.PermissionInterceptor:48] - 未进入主页面不拦截.....noInterceptPage:/login.jsp,/generate_image.do,/generate_code.do,/user_login.do,url:/user_login.do
2016-10-27 19:25:59,208 INFO [com.eshore.ismp.adminweb.portal.LoginController:59] - user_login method==inputCode:XA9Q===oldCode:XA9Q
2016-10-27 19:25:59,237 DEBUG [com.eshore.thrpc.client.DefaultInvoker:102] - Invoke to :ServerNode [ip=127.0.0.1, port=19096] ,method is process ,cost time :29
2016-10-27 19:25:59,237 INFO [com.eshore.ismp.adminweb.portal.LoginController:74] - user_login method===result:{"result_code":0,"result_detail":"success","result_data":"{\"mainMenu\":\"[{\\\"check\\\":false,\\\"createTime\\\":\\\"2016-10-21 11:03:38\\\",\\\"description\\\":\\\"\\\",\\\"id\\\":746,\\\"name\\\":\\\"动态编辑\\\",\\\"pId\\\":504,\\\"parentName\\\":\\\"动态管理\\\",\\\"seq\\\":1000,\\\"type\\\":\\\"00\\\",\\\"url\\\":\\\"./../customerWeb/dynamic/dynamicEdit.jsp\\\"}
2016-10-27 19:25:59,277 INFO [com.eshore.ismp.adminweb.filter.LoginFilter:58] - doFilter method===userId:1
2016-10-27 19:25:59,277 INFO [com.eshore.ismp.adminweb.filter.LoginFilter:59] - doFilter method===request.getRequestURI():/adminweb/common/index.jsp
2016-10-27 19:25:59,280 DEBUG [com.eshore.thrpc.client.DefaultInvoker:102] - Invoke to :ServerNode [ip=127.0.0.1, port=19090] ,method is process ,cost time :3
2016-10-27 19:25:59,280 INFO [com.eshore.ismp.adminweb.filter.LoginFilter:70] - doFilter method==result:{"result_code":0,"result_data":"{\"createTime\":\"2016-05-24 10:14:48\",\"creatorId\":\"1\",\"description\":\"\",\"email\":\"\",\"id\":1,\"loginName\":\"admin0\",\"mobilePhone\":\"18925121155\",\"name\":\"领航管理员\",\"nodeId\":1,\"orgName\":\"修改组织名称aa\",\"password\":\"E10ADC3949BA59ABBE56E057F20F883E\",\"phone\":\"18925121155\",\"type\":0,\"updateTime\":\"2016-08-03 15:39:47\"}","result_detail":"success"}
javax.servlet.http.Cookie@61ed61ec2016-10-27 19:25:59,506 INFO [com.eshore.ismp.adminweb.filter.LoginFilter:58] - doFilter method===userId:1
2016-10-27 19:25:59,507 INFO [com.eshore.ismp.adminweb.filter.LoginFilter:59] - doFilter method===request.getRequestURI():/adminweb/common/welcome.jsp
2016-10-27 19:25:59,509 DEBUG [com.eshore.thrpc.client.DefaultInvoker:102] - Invoke to :ServerNode [ip=127.0.0.1, port=19090] ,method is process ,cost time :2
2016-10-27 19:25:59,510 INFO [com.eshore.ismp.adminweb.filter.LoginFilter:70] - doFilter method==result:{"result_code":0,"result_data":"{\"createTime\":\"2016-05-24 10:14:48\",\"creatorId\":\"1\",\"description\":\"\",\"email\":\"\",\"id\":1,\"loginName\":\"admin0\",\"mobilePhone\":\"18925121155\",\"name\":\"领航管理员\",\"nodeId\":1,\"orgName\":\"修改组织名称aa\",\"password\":\"E10ADC3949BA59ABBE56E057F20F883E\",\"phone\":\"18925121155\",\"type\":0,\"updateTime\":\"2016-08-03 15:39:47\"}","result_detail":"success"}

  

可以看到dofilter是在拦截器之后执行

  总结:拦截器功在对请求权限鉴定方面确实很有用处,在我所参与的这个项目之中,第三方的远程调用每个请求都需要参与鉴定,所以这样做非常方便,而且他是很独立的逻辑,这样做让业务逻辑代码很干净。和框架的其他功能一样,原理很简单,使用起来也很简单,大致看了下SpringMVC这一部分的源码,其实还是比较容易理解的。

  我们项目中仅仅用到了preHandle这个方法,而未用其他的,框架提供了一个已经实现了拦截器接口的适配器类HandlerInterceptorAdapter,继承这个类然后重写一下需要用到的方法就行了,可以少几行代码,这种方式Java中很多地方都有体现。

以上部分是摘自神一样存在的博客参考了一下这个帖子:http://haohaoxuexi.iteye.com/blog/1750680

大家还可以参考一下这个电子书的截图:

进入拦截器链中的某个拦截器,并执行preHandle方法后
1.当preHandle方法返回false时,从当前拦截器往回执行所有拦截器的afterCompletion方法,再退出拦截器链。也就是说,请求不继续往下传了,直接沿着来的链往回跑
2.当preHandle方法全为true时,执行下一个拦截器,直到所有拦截器执行完。再运行被拦截的Controller。然后进入拦截器链,运行所有拦截器的postHandle方法,完后从最后一个拦截器往回执行所有拦截器的afterCompletion方法.

Java过滤器与SpringMVC拦截器之间的关系与区别的更多相关文章

  1. 160509、Java过滤器与SpringMVC拦截器之间的关系与区别

    今天学习和认识了一下,过滤器和SpringMVC的拦截器的区别,学到了不少的东西,以前一直以为拦截器就是过滤器实现的,现在想想还真是一种错误啊,而且看的比较粗浅,没有一个全局而又细致的认识,由于已至深 ...

  2. JAVA过滤器与SpringMVC拦截器之间的区别

    今天学习和认识了一下,过滤器和SpringMVC的拦截器的区别,学到了不少的东西,以前一直以为拦截器就是过滤器实现的,现在想想还真是一种错误啊, 而且看的比较粗浅,没有一个全局而又细致的认识,由于已至 ...

  3. Java过滤器,SpringMVC拦截器之间的一顺序点关系

    由于最近做的项目中有一部分是接口远程调用,用到了接入权限和业务权限的鉴定,需要采用SpringMVC的拦截器,以前用Struts2的时候用过拦截器,而SpringMVC的拦截器功能之前没研究过,所以这 ...

  4. servlet、过滤器、监听器、拦截器之间的关系和区别

    一.概念 1.什么是servlet servlet是一个接口.定义了一套处理网络请求的规范,所有实现servlet的类,都需要实现它那五个方法,其中最主要的是两个生命周期方法 init()和destr ...

  5. Java过滤器与SpringMVC拦截器的差异学习笔记

    学习摘录地址:http://blog.csdn.net/chenleixing/article/details/44573495 今天学习和认识了一下,过滤器和SpringMVC的拦截器的区别,学到了 ...

  6. Java Servlet 过滤器与 springmvc 拦截器的区别?

    前言:在工作中,遇到需要记录日志的情况,不知道该选择过滤器还是拦截器,故总结了一下. servlet 过滤器 定义 java过滤器能够对目标资源的请求和响应进行截取.过滤器的工作方式分为四种 应用场景 ...

  7. 阶段3 3.SpringMVC·_06.异常处理及拦截器_4 SpringMVC拦截器之介绍和搭建环境

    拦截器可以有多个 搭建环境 不用改,直接finish 复制原来项目的 依赖的包也复制过来 web.xml配置前端控制器 springmvc的配置文件 先创建对应的文件夹 分别创建java和resour ...

  8. java学习之SpringMVC拦截器开发

    0x00前言 springmvc的拦截器类似于Selvet的Filter,但是所属的操作又不一样 Spring MVC 提供了 Interceptor 拦截器机制,用于请求的预处理和后处理,也就是增强 ...

  9. 阶段3 3.SpringMVC·_06.异常处理及拦截器_7 SpringMVC拦截器之拦截器接口方法演示

    返回值改成false 就是不放行 没有方形,控制台只有一个输出 转发到error页面 新建error.jsp页面 控制台只有拦截器的输出.controller根本就没有执行 把代码改回来 重写第二个方 ...

随机推荐

  1. Ice的HelloWorld(Java)

    Ice是一种面向对象的中间间平台,入门ice,简单的HelloWorld是必不可少的. 转载请注明http://www.cnblogs.com/zrtqsk/p/3745286.html,谢谢. 一. ...

  2. Orchard CMS中如何打包不带源码的模块

    在Orchard CMS的官网已经提供了文档说明如何打包,但是如果使用它的打包方式,打好的nuget包是带源代码的.如果是为开源系统写模块,不需要关注源代码是否可见.但是如果是用Orchard CMS ...

  3. Python.Django视频教程(全13集)

    Python.Django视频教程(全13集)教程目录: 下载地址:http://www.fu83.cn/thread-205-1-1.html

  4. 完全背包变型题(hdu5410)

    这是2015年最后一场多校的dp题,当时只怪自己基础太差,想了1个多小时才想出来,哎,9月份好好巩固基础,为区域赛做准备.题目传送门 题目的意思是给你n元钱,m类糖果,每类糖果分别有p, a, b, ...

  5. 解决Package illuminate/html is abandoned, you should avoid using it. Use laravelcollective/html instead.问题

    解决步骤: 1.分析问题是因为laravel5.1不赞成使用illuminate/html而推荐使用laravelcollective/html包,所以我们利用composer命令移除illumina ...

  6. AJAX——核心XMLHttpRequest对象

    AJAX大家已经都知道了,是为了实现异步通讯,提高用户体验度,而将很多旧知识(XML,DOM,JavaScript,HTML,Jquery,Css……)重新融合的一个新的知识框架.而,XMLHttpR ...

  7. 东大OJ-5到100000000之间的回文质数

    1217: VIJOS-P1042 时间限制: 0 Sec  内存限制: 128 MB 提交: 78  解决: 29 [提交][状态][讨论版] 题目描述         有一天,雄霸传授本人风神腿法 ...

  8. 如果在敲代码的时候eclipse不弹出提示,怎么办?

    非常弱智的操作,我们曾经在输入System.out.println("content");的时候,当我们输入了"."之后,在输入错误,此时我们再回退至" ...

  9. go-- 用go-mssql驱动连接sqlserver数据库

    import _ "github.com/denisenkom/go-mssqldb" import ( "crypto/cipher" "crypt ...

  10. 理解 Paxos

    Paxos是前段时间刚获得图灵奖的大神Leslie Lamport所提出的,是用来解决分布式系统中的一致性问题的算法.该算法对于分布式系统的重要性,在这里不再赘言.了解过Paxos的朋友应该都知道,要 ...