zoukankan      html  css  js  c++  java
  • JavaWeb总结(九)

    过滤器

    - 一个中间组件,用于拦截源数据和目的数据之间的消息 

    - 过滤二者之间传递的数据

    Web应用上的过滤器 

    -驻留在Web服务器上的Web组件

    -过滤从客户端传递到服务器端的请求和响应 

     

    单个过滤器

      当Web容器接收到一个对资源的请求时,它将判断是否有过滤器器与这个资源相关联,如果有那么容器就把请求交给过滤器进行处理。在过滤器中,我们可以更改请求的内容,或者重新设置请求头,然后再将请求传递给目标资源。当目标资源对请求做出响应时,容器同样会将响应转发给过滤器,在过滤器中,我们可以对响应的内容进行更改,然后将响应发送回客户端。在Web应用程序中部署过滤器,对客户端和目标资源来说都是透明的,他们并不需要知道过滤器的存在。

    Web应用上部署多个过滤器 

     

    过滤器链

      过滤器可以组成一个过滤器链。链中的每个过滤器负责特定的操作和任务,客户端的请求和响应在这些过滤器之间传递 

      过滤器的一些常见应用:

    - 认证过滤:对用户请求进行统一的认证。

    - 登录和审核过滤:对用户的访问请求进行记录和审核。

    - 图像转换过滤:转换图像格式。

    - 数据压缩过滤 :对用户发生的数据进行压缩,从而减少传输量。

    - 加密过滤:对请求和响应进行加密解密处理。

    - 令牌过滤

    - 资源访问触发事件过滤 

    - XSLT过滤 

    - MIME-type过滤 

     Servlet的编码、编译、部署

      - 编码

        所有的过滤器必须实现javax.serlvet.Filter接口。实现Filter接口中定义的三个方法init()、doFilter()、destroy()。

      - 编译

        添加Servlet.jar包到工程jar包目录下。

      - 部署

        将编译好的class文件放置在Web应用程序的classes目录下

        在部署文件web.xml中添加过滤器的注册与映射

    <!--指定过滤器名和过滤器类-->
    <filter>
        <filter-name>HelloWorldFilter</filter-name>
        <filter-class>com.lovobook.HelloWorldFilter</filter-class>
    </filter>
        <!-- 将过滤器与URL模式关联-->
        <filter-mapping>
        <filter-name>HelloWorldFilter</filter-name>
        <url-pattern>/filter/*</url-pattern>
    </filter-mapping>

    过滤器API

      由容器实现的接口 

    - javax.servlet.Filter

    - javax.servlet.FilterChain

    - javax.servlet.FilterConfig 

      四个包装器类

    - javax.servlet.ServletRequestWrapper

    - javax.servlet.ServletResponseWrapper

    - javax.servlet.http.HttpServletRequestWrapper

    - javax.servlet.http.HttpServletResponseWrapper 

    Filter接口

    方法

    描述

    void init(FilterConfig)

    在应用程序启动时,由容器调用

    Void doFilter(ServletRequest, ServletResponse, FilterChain)

    对于每个URL映射到该过滤器的请求,由容器调用该方法。

    void destroy()

    在应用程序关闭时,由容器调用。

    - 过滤器的生命周期方法 ,过滤器API不提供Filter接口的任何实现 。自定义的过滤器必须明确地实现所有三个方法 

    - 容器仅调用过滤器实例的init()方法一次。在init()方法没有执行完前,容器不会转发任何请求到过滤器 

    - doFilter()方法给过滤器对象一个机会来处理请求,转发请求到过滤器链中的下一个组件,或者自己回复客户端 

    - destroy()是过滤器最后一个方法来调用,以指示过滤器生命周期的结束

    FilterConfig接口

    - 为过滤器提供初始化参数,并将对象作为参数传递给过滤器的init()方法

    - 提供了一个过滤器所在的应用程序ServletContext的应用

    - 由Servlet容器实现 

    方法

    描述

    String getFilterName()

    返回在部署描述文件中指定的过滤器的名称

    String getInitParameter(String)

    返回在部署描述文件中指定的参数的值

    Enumeration getInitParameterNames()

    返回在部署描述文件中指定的所有参数的名称。

    ServletContext getServletContext()

    返回Web应用程序的ServletContext。过滤器可以使用ServletContext设置、获取application范围内的属性。

    FilterChain接口

    - 由容器实现,由容器将其实例作为参数传到Filter接口的doFilter()方法 

    - 将请求传递到过滤器链的下一个组件 

    方法

    描述

    Void doFilter(ServletRequest, ServletResponse)

    我们从一个过滤器对象的doFilter()方法中调用此方法,以继续过滤器链的传递过程。它会将控制转到链中的下一个组件。

    配置Filter

      <filter>元素

     

    元素层次图

    <filter>
        <filter-name>ValidatorFilter</filter-name>
        <description>Validates the requests</description>
        <!--文件路径-->
        <filter-class>com.lovobook.filters.ValidatorFilter</filter-class>
        <!--初始参数-->
        <init-param>
            <param-name>locale</param-name>
            <param-value>USA</param-value>
        </init-param>
    </filter> 

      <filter-mapping>元素

     

    Filter-mapping结构图

     

    <!--所有匹配到该URL定义的请求,都要被filter-name中定义的过滤器过滤。-->
    <filter-mapping>
        <filter-name>ValidatorFilter</filter-name>
        <url-pattern>*.doc</url-pattern>
    </filter-mapping>
    <!--servlet-name用于定义一个servlet名,所有对该servlet的访问都要被filter-name中定义的过滤器过滤 -->
    <filter-mapping>
        <filter-name>ValidatorFilter</filter-name>
        <servlet-name>reportServlet</servlet-name>
    </filter-mapping> 

    配置过滤器链

    - 用多个过滤器处理在同一个请求 

    - 使用多个<filter-mapping>元素配置过滤器链

    - 首先调用匹配请求URI的过滤器<url-pattern>

    - 再查找用Servlet名匹配请求URI的所有过滤器<servlet-name>  

    - 过滤器的顺序按照它们在部署描述文件中出现的顺序排序  

     

    <filter-mapping>
          <filter-name>FilterA</filter-name>
          <servlet-name>RedServlet</servlet-name>
    </filter-mapping> 
    <filter-mapping>
          <filter-name>FilterB</filter-name>
          <url-pattern>*.red</url-pattern>
    </filter-mapping>
    <servlet-mapping>
          <servlet-name>RedServlet</servlet-name>
          <url-pattern>*.red</url-pattern>
     </servlet-mapping>
    <!--FilterA先执行?还是FilterB先执行?
    容器会先调用匹配请求URI的过滤器,然后才是匹配servlet名的过滤器。因此,FilterB始终在FilterA之前调用-->

     

     

    使用请求和响应包装器 

    - 所有的四个包装器类(包括ServletRequestWrapper、ServletResponseWrapper  、HttpServletRequestWrapper、HttpServletResponseWrapper的工作方式基本相同)。这四个类在其构造器中用request或response对象作为参数,并代理对两个对象的所有方法的调用。这样就运行我们扩充这些类,并使用自定义的行为覆盖类的方法

    - 在请求送到过滤器链的下一个组件之前更改请求的内容

    - 改变从前一个组件接收的响应

    public class MyRequestWrapper extends HttpServletRequestWrapper { 
         public MyRequestWrapper(HttpServletRequest req)  {
           super(req);
         } 
         //重写接口方法
       ……
    }

    public class MyResponseWrapper extends HttpServletResponseWrapper { public MyResponseWrapper(HttpServletResponse response) { super(response); } …… }

    public class TextToHTMLFilter implements Filter { …… public void doFilter(ServletRequest request,ServletResponse response, FilterChain filterChain) …{ MyRequestWrapper mrw = new MyRequestWrapper (req); MyResponseWrapper mrsw = new MyResponseWrapper(res); filterChain.doFilter(mrw , mrsw ); } }

    我不作恶

    但有权拒绝为善

    我不赞同

    但是我捍卫你不为善的权力

  • 相关阅读:
    基于事件的异步编程
    基于任务的异步编程
    C#异步编程
    C#2.0
    Mac上安装Brew
    PHP中三维数组转二位数组,并且根据某个字段去重
    LNMP环境安装Laravel之后, 除了根目录下可以访问, 其他都是404页面
    LNMP一键安装包安装的mysql远程连接不上的问题
    CentOS7 安装Redis4.0
    CentOS 7 源码包安装SVN及使用
  • 原文地址:https://www.cnblogs.com/HackerBlog/p/5970299.html
Copyright © 2011-2022 走看看