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

     • Filter 的基本功能是 Servlet 容器调用 Servlet 的过程进行拦截 从而在 Servlet 进行响应处理的前后实现一些特殊的功能
     • Servlet API 中定义了三个接口类来开供开发人员编写 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 ( FilterConfig filterConfig )throws ServletException :在 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 ( ServletRequest request,ServletResponse response,

     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 ( ServletRequest request,ServletResponse response)throws java.io.IOException :调用该方法将使过滤器链中的下一个过滤器被调用。如果是最后一个过滤器,会调用目标资源。

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

5.映射 Filter
< filter-mapping> 元素用于设置一个 Filter 所负责拦截的资源。一个 Filter 拦截的资源可通过两种方式来指定: Servlet 名称和资源访问的请求路径 ( url 样式 )
    – <filter-name> 子元素用于设置 filter 的注册名称。该值必须是在 <filter> 元素中声明过的过滤器的名字
    – < url -pattern> 设置 filter 所拦截的请求路径 ( 过滤器关联的 URL 样式 )
    – < servlet -name> 指定过滤器所拦截的 Servlet 名称。
    – <dispatcher> 指定过滤器所拦截的资源被 Servlet 容器调用的方式 ,可以是 REQUEST,INCLUDE,FORWARD ERROR 之一,默认 REQUEST. 可以设置多个 <dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截
<dispatcher> 子元素可以设置的值及其意义:
    – REQUEST :当用户直接访问页面时, Web 容器将会调用过滤器。如果目标资源是通过 RequestDispatcher include() forward() 方法访问时,那么该过滤器就不会被调用。通过 GET 或 POST 请求直接访问。
    – INCLUDE :如果目标资源是通过 RequestDispatcher include() 方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。<jsp:include file="/..." />
    – FORWARD :如果目标资源是通过 RequestDispatcher forward() 方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。 <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 就是想要装饰的对象: public MessagerDecorator ( Messager messager )
    – 重写 getMessage 方法,让重写的方法用大写字母来返回 message 属性

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

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

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




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值