zoukankan      html  css  js  c++  java
  • 过滤器

    概述

    1、Web 过滤器是一种特殊的 Servlet,Servlet 过滤器介于与之相关的 Servlet 或 JSP 页面与客户端之间,它可以对用户的请求信息和响应信息进行过滤处理,将非法或不需要的信息删除。
    2、基于 Filter 技术的特点,Web 开发人员可以对 Web 服务器管理的所有 Web 资源(Jsp、Servlet、静态图片文件或静态 html 文件等)进行拦截,从而实现一些特殊的功能。例如实现 URL 级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

    Filter工作原理

    1、当某个资源与 Servlet 过滤器关联后,对该资源的所有请求都会经过 Servlet 过滤器,Servlet 过滤器在 Servlet 被调用之前会检查请求对象(Request 对象),并决定是将请求转发给过滤器链中的下一个资源还是中止该请求并响应用户。
    2、当用户访问 Web 页面请求时,通过 Web 容器进入访问 Servlet 过滤器所对应的 Servlet 时,先执行设置好的 Filter 过滤器,对请求和响应的信息通过 FilterChain.doFilter() 方法进行过滤。
    3、过滤后的请求信息才被传送到对应的 Servlet 中。可以指定 Servlet 过滤器和特定的 URL 关联,只有当客户请求访问此 URL 的时候,才会触发过滤器工作。

    Filter 生命周期

    1、Web 应用加载后会立即创建出当前 Web 应用中的 Filter 对象,创建出来后,立即调用 init 方法进行初始化出操作,它们都提供了 init (FilterConfig arg0)destroy () 方法来控制,当关闭 Web 容器,关机或者 reload 整个应用时,都会调用 destroy () 来关闭 Filter。
    2、也就是说,当 Web 容器启动时,Filter 就被加载到内存,并在 destroy ()调用之前都常驻内存。

    Filter 链

    在一个 web 应用中,可以开发编写多个 Filter,这些 Filter 组合起来称之为一个 Filter 链。
    Web 服务器根据 Filter 在 web.xml 文件中的注册顺序,决定先调用哪个 Filter ,当第一个 Filter 的 doFilter 方法被调用时, Web 服务器会创建一个代表 Filter 链的 FilteChain 对象传递给该方法。在 dofilter 方法中,开发人员如果调用了 FilterChain 对象的 dofilter 方法,则 Web 服务器会检查 FilterChain 对象中是否还有 Filter ,如果有,则调用第2个 Filter ,如果没有,则调用目标资源。
    在这里插入图片描述

    Filter的工作流程

    在这里插入图片描述
    1、独立的 Servlet 过滤器可以被串联在一起,形成管道效应,协同修改请求和响应对象。每个 Servlet 完成不同的过滤功能。
    2、过滤器机制是由 javax.Servlet 包中的 Filter、FilterChain 和 FilteConfig 接口类组成,FilterChain包含一个 Filter 数组,当 Wrapper 执行 FilterChain 的 doFilter (request, response) 方法时,FilterChain 首先调用第一个 Filter 的 doFilter (request, response, filterchain) 方法;当第一个 Filter 做完过滤操作后,它又会调用 Filterchain 的 doFilter 方法,此时 Filterchain 的当前 Filter 已变为第二个 Filter ,第二个 Filter 执行 doFilter 方法,依此类推,直至所有过滤器都执行完毕。
    3、创建过滤器须实现 javax.servlet.Filter 接口,该接口内定义了3个方法。

    javax.servlet.Filter 接口中的3个方法

    init (FilterConfig config)

    1、用于初始化过滤器,并获取 web.xml 文件中配置的过滤器初始化参数。
    2、FilterConfig 用于检索过滤器名、初始化参数以及活动的 Servlet 上下文,方法如下。

    • getFilterName()
      获得过滤器名称。
    • getInitParameter(String name)
      获得过滤器初始化参数。
    • getInitParameterNames()
      获取过滤器的所有初始化参数名称。
    • getServletContext()
      获得 ServletContext 对象。
    doFilter (ServletRequest reg, ServletResponse res, FilterChain chain)

    1、用于进行过滤操作,该方法的第一个参数为 SerleRequest 对象,此对象给过滤器提供了对进入的信息(包括表单数据、Cookie 和 HTTP 请求头)的完全访问。
    2、第二个参数为 ServletResponse ,用于响应使用 ServletRequest 对象访问的信息,通常在简单的过滤器中忽略此参数。
    3、最后一个参数为 FillerChain,该参数用来调用过滤器链中的下一个资源。FilterChain参数用于访问后续过滤器。

    destroy ()

    Servlet 容器在销毁过滤器实例前调用该方法,这个方法中可以释放 Servlet 过滤器占用的资源。性质等同于 servlet 的 destory() 方法。

    Filter开发步骤

    Servlet 过滤器的创建步骤如下:
    1、实现 javax.servlet.Filter接口的servlet类。
    2、实现 init 方法,读取过滤器的初始化参数。
    3、实现 doFilter 方法,完成对请求或响应的过滤。
    4、调用 FilterChain 接口对象的 doFilter 方法,向后续的过滤器传递请求或响应。
    5、在 web.xml 中配置 Filter。

    Filter 的创建

    Servlet API 中提供了一个 Filter 接口,开发 Web 应用时,如果编写的 Java 类实现了这个接口,则把这个 Java 类称之为过滤器 Filter ,编写 Java 类实现 Filter 接口,要编写一个过滤器必须实现 Filter 接口,实现其接口规定的方法有以下几种。
    1、实现 javax.servlet.Filer接口。
    2、实现 init 方法,读取过滤器的初始化参数。
    3、实现 doFilter 方法,完成对请求或响应的过滤。
    4、调用 FilterChain 接口对象的 doFilter 方法,向后续的过滤器传递请求或响应。

    Filter 的配置

    Filter 通过 Web 应用程序中的配置文件 Web.xml 添加过滤器配置信息的声明。

    <!--配置过滤器--> 
    <filter> 
     	 	<filter-name>oneFilter</filter-name> 
     	 	<!--filter的名字-->
       	 	<filter-class>com.filter.Myfilter</filter-class> 
       	 	<!--filter的类全路径-->
    	<init-param>
    		<param-name>param1</param-name>
    		<param-value>value</param-value>
    	</init-param>
    </filter> 
    <!--映射过滤器--> 
    <filter-mapping> 
        <filter-name>oneFilter</filter-name> 
        <!--和filter的名字一一对应-->
        <url-pattern>/*</url-pattern>
        <!--“/*”表示拦截所有的请求 -->
        <dispatcher>dispatcher1(request)</dispatcher>
        <dispatcher>dispatcher2(include)</dispatcher>
        <servlet-name>servletname</servlet-name>
    </filter-mapping>
    

    <filter > 标签定义过滤器的名称,并且声明实现类和 ini() 参数,其中 init-param 为定义初始化参数,可以设置多个,在定义的过滤器中再次实现 init 方法,即可读取过滤器的初始化参数。
    <filer-mapping > 标签将定义的过滤器与 servlet 或 URL 模式等服务器资源相关联。通知Tomcat在调用何种资源文件之前需要调用 oneFilter 过滤器进行拦截。
    <url-pattern > 标签使用URL模板将过滤器映射到 JSP 和 HTML 等资源,可以指定 某个资源 或 多个 或 所有资源。
    <servlet-name> 标签指定某个servlet。

    URL模式 含义
    /* 根路径下的所有资源
    /servlet/* /servlet路径下的所有资源
    /jsp/*.jsp /jsp路径下的所有jsp页面
    /dept/accounting/* /dept/accounting/路径下的所有资源
    /index.html 指定当前 Web 应用程序的 index.html页面
    *.jpg 任意文件夹下某种(这里是jpg类型)类型文件
    dispatcher参数

    在映射过滤器的时候,有一个 dispatcher 参数,指定过滤器所拦截的资源被 Servlet 容器调用的方式。在 Servlet2.5 中有四个取值,分别为 request、include、forward、error,不填时默认为 request。用户可以设置多个<dispatcher>子元素来指定 Filter 对资源的多种调用方式进行拦截。

    • request
      当用户直接访问页面时,web 容器将会调用过滤器,如果目标资源是通过请求转发(request.getRequestDisPatcher)的 include 方法或 forward 方法进行访问或 error 情况,那么该过滤器就不会被调用。
    • include
      如果目标资源是通过 request.getRequestDisPatcher 的 include 方法进行访问,那么该过滤器将会被调用,其他情况下,不会被调用。
    • forward
      如果目标资源是通过 request.getRequestDisPatcher 的 forward 方法进行访问,那么该过滤器将会被调用,其他情况下,不会被调用。
    • error
      如果目标资源是通过声明或异常处理机制调用,那么该过滤器将会被调用,除此之外,不会被调用。

    Filter 的应用案例

    1、用户认证与授权管理。
    2、统计 Web 应用的访问量和访问的命中率,形成访问报告。
    3、实现 Web 应用的日志处理功能。
    4、实现数据压缩功能。
    5、对传输的数据进行加密。
    6、实现 XML 文件的 XSLT 转换。
    7、中文乱码的处理。
    8、过滤敏感信息。

    代码示例(检测请求的合法性)

    • index.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>首页</title>
      </head>
        <body>
            这是首页!
        </body>
    </html>
    
    • first.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>First</title>
    </head>
        <body>
            登录成功!
        </body>
    </html>
    
    • OneServlet
    package com.aaa;
    
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @author zzz
     * http://localhost:8080/Web/one?name=qwe&key=111
     */
    public class OneServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
            String name = req.getParameter("name");
            if ("qwe".equals(name)) {
                try {
                    resp.sendRedirect("/Web/first.jsp");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }else {
                try {
                    resp.sendRedirect("/Web/index.jsp");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    • OneFilter
    package com.aaa;
    
    import javax.servlet.*;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    public class OneFilter implements Filter {
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("doFilter");
            //通过拦截请求对象得到请求包参信息
            String key = servletRequest.getParameter("key");
            if ("111".equals(key)){
                //将拦截请求对象和响应对象交还给Tomcat,由Tomcat继续调用资源文件(放行)
                filterChain.doFilter(servletRequest,servletResponse);
            }else {
                servletResponse.setContentType("text/html;charset=utf-8");
                PrintWriter out = servletResponse.getWriter();
                out.print("<center>
    " +
                        "    <font style='color:red; font-size:40px'> 
    " +
                        "        key错误!
    " +
                        "    </font>
    " +
                        "</center>");
            }
        }
    
        @Override
        public void destroy() {
            System.out.println("destroy");
        }
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("init");
        }
    }
    
    • XML配置
    <filter>
        <filter-name>oneFilter</filter-name>
        <filter-class>com.aaa.OneFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>oneFilter</filter-name>
        <url-pattern>/one</url-pattern>
    </filter-mapping>
    
    
    <servlet>
        <servlet-name>oneServlet</servlet-name>
        <servlet-class>com.aaa.OneServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>oneServlet</servlet-name>
        <url-pattern>/one</url-pattern>
    </servlet-mapping>
    

    启动服务器:
    在这里插入图片描述
    在这里插入图片描述

    • 第一种:输入错误的name和正确的key:
      在这里插入图片描述
      name错误会返回首页:
      在这里插入图片描述
    • 第二种:输入正确的name和错误的key:
      在这里插入图片描述
    • 第三种:输入正确的name和正确的key:
      在这里插入图片描述
      登录成功:
      在这里插入图片描述
      在这里插入图片描述
    • 关闭服务器
      在这里插入图片描述

    过滤器对拦截的请求进行增强操作

    每个 Servlet 都要做的事情可以交给过滤器来做,对 Servlet 进行增强。如下图:
    在这里插入图片描述

    过滤器防上用户恶意登录行为

    用户通过修改地址栏对服务器索要资源,为防止其发生,在访问前进行过滤操作。

    • 无过滤器
      在这里插入图片描述
    • 使用过滤器
      在这里插入图片描述
  • 相关阅读:
    16进制数至字符串转换
    综合评价模型C++实现
    综合评价模型
    Eigen使用矩阵作为函数参数
    Eigen子矩阵操作
    Eigen矩阵基本运算
    c++矩阵运算库Eigen简介
    三次样条插值算法C++实现
    一个 图片 滚动 飞入的css特效
    在TTF字体中提取想要的文字
  • 原文地址:https://www.cnblogs.com/yu011/p/14238166.html
Copyright © 2011-2022 走看看