过滤器Filter

来源:互联网 发布:非主流文化 知乎 编辑:程序博客网 时间:2024/05/16 08:12

概述

过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。


过虑器可以对Web组件的ServletRequest和ServletResponse进行检查和修改。
过虑器能对客户的请求HttpServletRequest进行预处理,也可以对HttpServletResponse进行后处理。


过虑器本身并不生成ServletRequest对象和ServletResponse对象,它只对web组件提供以下过虑功能:
  • 在web组件调用之前检查request,并修改请求头和请求正文。
  • 过虑器能够在web组件被调用之后检查response对像,修改响应头和响应正文。
使用过滤器的完整步骤:
  1. 在HttpServletRequest到达Servlet之前,拦截它。
  2. 根据需要检查HttpServletRequest,也可以修改它的头和数据。
  3. 在HttpServletResponse到达客户端之前,拦截它。
  4. 根据需要检查HttpServletResponse,也可以修改它的头和数据


 过滤器的生命周期

我们已经学习过Servlet的生命周期,那么Filter的生命周期也就没有什么难度了!

  • init(FilterConfig):在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次;
  • doFilter(ServletRequest req,ServletResponse res,FilterChain chain):这个方法会在用户每次访问“目标资源(<url->pattern>index.jsp</url-pattern>)”时执行,如果需要“放行”,那么需要调用FilterChaindoFilter(ServletRequest,ServletResponse)方法,如果不调用FilterChaindoFilter()方法,那么目标资源将无法执行;
  • destroy():服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法。

    自定义过滤器

自定义的过虑器必须实现:javax.servlet.Filter接口。此接口定义了以下三个方法:
  • Init(FilterConfig conf) – 过虑器的初始化方法。初始化工作执行一次(启动时)。
  • doFilter(ServletRequest,ServletResponse,FilterChain) – 完成实际的过虑操作。只要是配置的url匹配此过虑器的配置,即执行此方法。
  • destroy()-Servlet窗口在销毁过虑器时执行此方法。销毁工作也只执行一次。
1.实现Filter类并实现doFilter()方法。
2.在web.xml中配置过滤器。

 FilterChain

doFilter()方法的参数中有一个类型为FilterChain的参数,它只有一个方法:doFilter(ServletRequest,ServletResponse)我们说doFilter()方法的放行,让请求流访问目标资源!但这么说不严密,其实调用该方法的意思是,当前Filter放行了,但不代表其他其他过滤器也放行。也就是说,一个目标资源上,可能部署了多个过滤器,就好比在你去北京的路上有多个打劫的匪人(过滤器),而其中第一伙匪人放行了,但不代表第二伙匪人也放行了,所以调用FilterChain类的doFilter()方法表示的是执行下一个过滤器的doFilter()方法,或者是执行目标资源!如果当前过滤器是最后一个过滤器,chain.doFilter()方法表示执行目标资源。反之,chain.doFilter()表示执行下一个过滤器的doFilter()方法。


   多个过滤器执行顺序

一个目标资源可以指定多个过滤器,过滤器的执行顺序是在web.xml文件中的部署顺序


   拦截器与过滤器的区别

  • 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
  • 拦截器不依赖于servlet容器,过滤器依赖servlet容器。
  • 拦截器只能对action请求起作用(还记得struts2中的拦截器栈吗?),而过滤器则可以对几乎所有的请求起作用。
  • 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  • 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

还记得CharacterEncodingFilter吗?


 过滤器的应用场景

  • 执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;request.setCharacterEncoding(“utf-8”)
  • 通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;
  • 在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理;
过滤器的种类:
  1. 用户授权的Filter:负责检查用户请求,根据请求过滤用户非法请求。
  2. 日志Filter:            详细记录某些特殊用户的请求
  3. 负责解码的Filter:包括对非标准码的请求解码
  4. XSLT fitler:          能改变XML内容
案例一:分ip统计网站的访问次数

案例二:禁用缓存过滤器

案例三:粗粒度权限控制‘

案例四:编码过滤器

Not finished!!!

0 0
原创粉丝点击