Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
   通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以在某资源向web容器返回响应前进行截获进行处理。如下所示:

  Servlet过滤器和SpringMVC的拦截器是有区别的,区别如下:

       ①拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
  ②拦截器不依赖于servlet容器,过滤器依赖于servlet容器。
  ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
  ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

  注:在网页编程中action是<form>表单标签的属性,指代的是当用户提交这张表单的时候由哪张页面来进行处理,一般使用方式是:<form action=”处理页面路径”method=”post或get”>。表明表单提交后转到action指明的动作(其实就是java文件),在这个动作中可以得到表单的数据,并对这些数据进行操作。在这个动作中可以得到表单的数据,并对这些数据进行操作。

   一个Filter必须实现javax.servlet.Filter接口的三个方法:
   void setFilterConfig(FilterConfig config) //设置Filter的配置对象;
   FilterConfig getFilterConfig() //返回Filter的配置对象;
   void doFilter(ServletRequest req,ServletResponse res,FilterChain chain) //执行Filter的工作

   Filter接口中有一个doFilter方法,当开发人员编写好Filter类实现doFilter方法,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前(服务器内部对资源的访问机制决定的),都会先调用一下Filter的doFilter方法。

过滤器应用举例:

public class EncodingFilter implements Filter {    private String encoding = null;    public void destroy() {    encoding = null;    }    public void doFilter(ServletRequest request, ServletResponse response,    FilterChain chain) throws IOException, ServletException {    String encoding = getEncoding();    if (encoding == null){    encoding = ”gb2312”;    }    request.setCharacterEncoding(encoding);//在请求里设置指定的编码    chain.doFilter(request, response);  //通过控制对chain.doFilter的方法的调用,来决定是否需要访问目标资源  }    public void init(FilterConfig FilterConfig) throws ServletException {    this.encoding = FilterConfig.getInitParameter(“encoding”);    }    private String getEncoding() {    return this.encoding;    }    }    

XML配置代码:

<Filter>    <Filter-name>EncodingFilter</Filter-name>    <Filter-class>com.logcd.Filter.EncodingFilter</Filter-class>    <init-param>    <param-name>encoding</param-name>    <param-value>gb2312</param-value>    </init-param>
</Filter>    <Filter-mapping>    <Filter-name>EncodingFilter</Filter-name>    <url-pattern>/*</url-pattern>
</Filter-mapping>    

  以上代码完成的功能为,无论进入哪个页面,都要先执行EncodingFilter类的doFilter方法设置字符集。其中,doFilter()方法类似于Servlet接口的service()方法。当客户端请求目标资源的时候,容器就会调用与这个目标资源相关联的过滤器的doFilter()方法。参数 request, response 为web 容器或 Filter 链的上一个 Filter 传递过来的请求和相应对象;参数 chain 代表当前 Filter 链的对象。 对于FilterChain接口,代表当前Filter链的对象。由容器实现,容器将其实例作为参数传入过滤器对象的doFilter()方法中。过滤器对象使用FilterChain对象调用过滤器链中的下一个过滤器,或者目标Servlet 程序去处理,也可以直接向客户端返回响应信息,或者利用RequestDispatcher的forward()和include()方法,以及HttpServletResponse的sendRedirect()方法将请求转向到其他资源。这个方法的请求和响应参数的类型是 ServletRequest和ServletResponse,也就是说,过滤器的使用并不依赖于具体的协议。

   和Servlet一样,Filter的创建和销毁也是由Web容器负责。

  Filter的主要的作用就是用户在访问某个目标资源之前,对访问的请求和响应进行拦截,做一些处理,然后再调用目标程序,这样做的好处是可以对一些公共的操作进行抽象,就拿设置字符集来说,如果不使用这种方式,我们每个页面都要写设置字符集的语句。不但麻烦而且维护困难,但是如果使用Filter的话,只需要添加一个类,在xml中配置一下,如果不想使用了,将配置文件中的内容去除即可。Filter基于回调函数,我们需要实现的Filter接口中doFilter方法就是回调函数。

  当客户端发出Web资源的请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请求数据进行检查或改动,并依次通过过滤器链,最后把请求/响应交给请求的Web资源处理。

  请求信息在过滤器链中可以被修改,也可以根据条件让请求不发往资源处理器,并直接向客户机发回一个响应。当资源处理器完成了对资源的处理后,响应信息将逐级逆向返回。同样在这个过程中,用户可以修改响应信息,从而完成一定的任务。

  过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。

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

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

@Overridepublic 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、拦截器是被包裹在过滤器之中的。

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

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

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

  afterCompletion()方法是在过滤器返回给前端的前一步执行,也就是在chain.doFilter(request, response)和System.out.println(“after…”)之间执行。

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

  

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

  Spring框架提供了一个已经实现了拦截器接口的抽象配器类HandlerInterceptorAdapter,继承这个类然后重写一下需要用到的方法就行了,可以少几行代码,这种方式Java中很多地方都有体现。

Servlet过滤器与SpringMVC拦截器相关推荐

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

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

  2. jsp/servlet过滤器和struts2拦截器的有什么区别

    jsp/servlet过滤器和struts2拦截器的有什么区别 542430725 | 浏览 3715 次  问题未开放回答  推荐于2016-11-14 01:43:29 最佳答案 过滤器,是在ja ...

  3. java jax-rs拦截器_java – Servlet过滤器与CXF拦截器,用于修改请求和响应内容?

    在这里回答我自己的问题-我最终使用了一个JAX-RS过滤器,一旦我缺少文档,它就能很好地运行.我使用了 http://cxf.apache.org/docs/jax-rs-filters.html的( ...

  4. JAVA incept_java 过滤器(Filter)与springMVC 拦截器(interceptor)的实现案例

    java 过滤器Filter: package com.sun.test.aircraft.filter; import javax.servlet.*; import java.io.IOExcep ...

  5. SpringMVC拦截器与Filter过滤器

    SpringMVC拦截器与Filter过滤器 SpringMVC拦截器与Filter过滤器 Spring MVC拦截器的定义 SpringMVC拦截器的配置 SpringMVC拦截器HandlerIn ...

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

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

  7. Spring+SpringMVC+MyBatis深入学习及搭建(十七)——SpringMVC拦截器

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7098753.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十六)--S ...

  8. SpringMVC拦截器(interceptors)

    一.什么是拦截器? spring提供的一个特殊的组件,当DispatcherServlet收到请求之后,如果有拦截器,会先调用拦截器,然后调用响应的处理器(Controller). 注: 过滤器属于s ...

  9. SpringBoot中AOP实现落地——Filter(过滤器)、Intercepter(拦截器)、Aspect(Spring AOP)

    文章目录 一.一切要从Servlet说起 1.1什么是Servlet 1.2为什么需要Servlet 1.3Servlet如何响应用户请求 1.4Servlet与Tomcat处理请求的流程 1.5Se ...

最新文章

  1. CF449B Jzzhu and Cities 迪杰斯特拉最短路算法
  2. linux 内核 printk 使用
  3. 冒泡排序java代码_数据结构与算法—冒泡排序(Java实现)
  4. 2018.3.30 边框应用与导航栏设置
  5. ios开发 多人语音聊天_在 Unity 多人游戏中实现语音对话
  6. 机器学习速成课程 | 练习 | Google Development——编程练习:特征组合
  7. 使用flask快速搭建API
  8. linux tar.7z如何解压,Linux下解压:tar、rar、7z命令简单易懂的教程(含实例)
  9. java.lang.IllegalArgumentException: MALFORMED 解决方法
  10. 如何通过数据进行网站分析
  11. 华清远见第一周学习体会
  12. 区块链游戏的抢滩之战
  13. 学习 Rust Futures - Future 和 Stream
  14. Python sqlite3 (no such table:xxx)
  15. python 乘法运算定律_乘法运算定律专项练习题
  16. 脑洞大开:为啥帧率达到 60 fps 就流畅?
  17. Maya实例:怎么建一条绳子
  18. 如何玩转微软新版 Edge 浏览器?
  19. 关于Unity中红外线瞄准的效果实现
  20. mtk android wifi,MTK android WIFI地址 不写随机变动问题

热门文章

  1. Visual Studio安装及下载
  2. 提高微信小程序搜索排名的一些技巧
  3. C#使用ODAC向Oracle数据库插入海量实时数据
  4. 【收藏】安科瑞企业微电网能效管理系统云平台演示账号
  5. java简单版扫雷实现
  6. jquery设置图片比例
  7. 使用华为云搭建属于自己的云端开发环境
  8. java jbutton文字_JAVA swing JLabel JButton标签文本文字内容的换行
  9. Python人工智能
  10. Scrapy 爬虫 官方 中文文档 开发手册