javaWeb基础知识----过滤器Filter

来源:互联网 发布:发型p图软件 编辑:程序博客网 时间:2024/06/05 11:45

     •Filter 的基本功能是Servlet容器调用Servlet的过程进行拦截从而在Servlet进行响应处理的前后实现一些特殊的功能
     •ServletAPI中定义了三个接口类来开供开发人员编写Filter程序:Filter,FilterChain,FilterConfig
     •Filter 程序是一个实现了Filter接口的 Java,与Servlet程序相似,它由Servlet容器进行调用和执行
     •Filter 程序需要在 web.xml文件中进行注册和设置它所能拦截的资源Filter程序可以拦截Jsp,Servlet,静态图片文件和静态html文件

1.Filter的基本工作原理

    •web.xml中注册了一个Filter来对某个Servlet程序进行拦截处理时,这个Filter就成了Servlet容器与该Servlet程序的通信线路上的一道关卡,该Filter可以对Servlet容器发送给Servlet程序的请求和Servlet程序回送给Servlet容器的相应进行拦截,可以决定是否将请求继续传递给Servlet程序,以及对请求和相应信息是否进行修改
    •在一个web应用程序中可以注册多个Filter程序,每个Filter程序都可以对一个或一组Servlet程序进行拦截。
    •若有多个Filter程序对某个Servlet程序的访问过程进行拦截,当针对该Servlet的访问请求到达时,web容器将把这多个Filter程序组合成一个Filter(过滤器链)Filter链中各个Filter的拦截顺序与它们在应用程序的web.xml映射的顺序一致

2.Filter 接口

    1).init(FilterConfigfilterConfig)throwsServletException:在web应用程序启动时,web服务器将根据web.xml文件中的配置信息来创建每个注册的Filter实例对象,并将其保存在服务器的内存中。Web容器创建Filter对象实例后,将立即调用该Filter对象的 init方法Init方法在Filter生命周期中仅执行一次web容器在调用init方法时,会传递一个包含Filter的配置和运行环境的 FilterConfig对象(FilterConfig的用法和ServletConfig类似)利用FilterConfig对象可以得到ServletContext对象,以及部署描述符中配置的过滤器的初始化参数在这个方法中,可以抛出ServletException异常,通知容器该过滤器不能正常工作
    2).destroy():在Web容器卸载Filter对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源
与开发Servlet不同的是,Filter接口并没有相应的实现类可供继承,要开发过滤器,只能直接实现Filter接口
    3).doFilter(ServletRequestrequest,ServletResponseresponse,

     FilterChainchain)throwsjava.io.IOException,ServletException

     doFilter()方法类似于Servlet接口的service()方法当客户端请求目标资源的时候,容器就会调用与这个目标资源相关联的过滤器的doFilter()方法其中参数request,responseweb 容器或Filter链的上一个Filter传递过来的请求和相应对象;参数chain为代表当前Filter链的对象,在特定的操作完成后可以在当前Filter对象的doFilter方法内部需要调用FilterChain对象的chain.doFilter(request,response)方法才能把请求交付给Filter链中的下一个Filter 或者目标 Servlet程序去处理,也可以直接向客户端返回响应信息,或者利用RequestDispatcher的forward()include()方法,以及HttpServletResponse的sendRedirect()方法将请求转向到其他资源。这个方法的请求和响应参数的类型是ServletRequest和ServletResponse,也就是说,过滤器的使用并不依赖于具体的协议。

3.FilterChain接口

FilterChain接口:代表当前Filter链的对象。由容器实现,容器将其实例作为参数传入过滤器对象的doFilter()方法中。过滤器对象使用FilterChain对象调用过滤器链中的下一个过滤器,如果该过滤器是链中最后一个过滤器,那么将调用目标资源。
  1).doFilter(ServletRequestrequest,ServletResponseresponse)throwsjava.io.IOException:调用该方法将使过滤器链中的下一个过滤器被调用。如果是最后一个过滤器,会调用目标资源。

4.FilterConfig接口

javax.servlet.FilterConfig接口:该接口类似于ServletConfig接口,由容器实现。Servlet规范将代表ServletContext对象和Filter的配置参数信息都封装在该对象中。Servlet容器将其作为参数传入过滤器对象的init()方法中。
    •String getFilterName():得到描述符中指定的过滤器的名字。
    •String getInitParameter(Stringname): 返回在部署描述中指定的名字为name的初始化参数的值。如果不存在返回null.
    • Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名字的枚举集合。
    •public ServletContextgetServletContext():返回Servlet上下文对象的引用。

5.映射 Filter

<filter-mapping>元素用于设置一个Filter所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet名称和资源访问的请求路径(url样式)
    –<filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字
    –<url-pattern>设置filter所拦截的请求路径(过滤器关联的URL样式)
    –<servlet-name>指定过滤器所拦截的Servlet名称。
    –<dispatcher>指定过滤器所拦截的资源被Servlet容器调用的方式,可以是REQUEST,INCLUDE,FORWARDERROR之一,默认REQUEST.可以设置多个<dispatcher>子元素用来指定Filter对资源的多种调用方式进行拦截
<dispatcher> 子元素可以设置的值及其意义:
    –REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcherinclude()forward()方法访问时,那么该过滤器就不会被调用。通过 GET 或 POST 请求直接访问。
    –INCLUDE:如果目标资源是通过RequestDispatcherinclude()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。<jsp:include file="/..." />
    –FORWARD:如果目标资源是通过RequestDispatcherforward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。 <jsp:forward page="/..." /> 或 通过 page 指令的 errorPage 转发页面. <%@ page errorPage="test.jsp" %>
    –ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。在 web.xml 文件中通过 error-page 节点进行声明:
    •在同一个 web.xml文件中可以为同一个Filter设置多个映射。若一个Filter链中多次出现了同一个Filter程序,这个Filter程序的拦截处理过程将被多次执行

6.典型应用

1•使浏览器不缓存页面的过滤器
  –3 HTTP响应头字段都可以禁止浏览器缓存当前页面,它们在Servlet中的示例代码如下:
    •response.setDateHeader("Expires",-1);
    •response.setHeader("Cache-Control","no-cache"); 
    •response.setHeader("Pragma","no-cache"); 
  –并不是所有的浏览器都能完全支持上面的三个响应头,因此最好是同时使用上面的三个响应头
2.字符编码的过滤器
通过配置参数encoding指明使用何种字符编码,以处理HtmlForm请求参数的中文问题

3.检测用户是否登陆的过滤器
    –情景:系统中的某些页面只有在正常登陆后才可以使用,用户请求这些页面时要检查 session中有无该用户信息,但在所有必要的页面加上session的判断相当麻烦的事情
    –解决方案:编写一个用于检测用户是否登陆的过滤器,如果用户未登录,则重定向到指的登录页面
    –要求:需检查的在 Session中保存的关键字;如果用户未登录,需重定向到指定的页面(URL不包括ContextPath);不做检查的URL列表(以分号分开,并且URL中不包括ContextPath)都要采取可配置的方式
4.利用Filter限制用户浏览权限

5.装饰 HttpServletRequest对象
    •需求:在 HttpServletRequest对象到达Servlet之前把用户输入的多余空格都去掉
    •情景:因为 HttpServletRequest对象里的请求参数都实际包含在java.util.Map对象里,而Map是不允许修改的,所以包含在HttpServletRequest对象里的请求参数不能被修改
    •解决方案:采取 Decorator(装饰器)模式

7、Decorator 模式

    •因为继承的关系,当需要改变某个对象的行为时,只须扩展这个对象所属的类并重写其有关的方法就可以达到目的。但是,当想要改变其行为的对象是由应用程序里的另一个子系统(例如:一个对象工厂或是一个Servlet容器)负责构造,继承机制将无能为力
  •需求:让 broadcast方法打印的字母都是大写字母
  •方案:从 Messager类派生一个子类,把子类对象传递给broadcast方法。因为只有对象工厂知道如何初始化Messager对象,所以该方案无意义
  •Decorator 模式:
    –Messager类派生一个子类MessagerDecorator,把子类对象传递给broadcast方法
    –MessagerDecorator类里实现构造器:接受一个Messager对象作为输入参数,而这个Messager就是想要装饰的对象:publicMessagerDecorator(Messagermessager)
    –重写 getMessage方法,让重写的方法用大写字母来返回message属性

典型应用5:为论坛过滤不雅文字和HTML特殊字符

开发论坛模块时要解决以下两个问题:
1. 用户回复或发帖时可能会输入HTML代码(例如:<,>),这可能会破坏论坛的正常显示,也可能会带来安全隐患。
2. 某些用户在回复时可能会输入不雅子句,这些子句会给论坛带来不好的影响
3. 实现对不雅文字的可配置
要求:不雅文字及其替换内容实现可配置。如i shit you  i **** you

例子:开发一个留言板程序




0 0
原创粉丝点击