zoukankan      html  css  js  c++  java
  • [10] 过滤器 Filter


    1、过滤器的基本概念和作用

    在网站的页面访问时,我们往往需要做一些控制,如普通用户无法访问VIP用户的页面。如果在每一个需要访问控制的文件中都加上判断代码,那么代码将会很冗余,一旦需要统一修改时也极其繁琐。

    过滤器就可以解决这样的问题,配置完成的过滤器,会强制让指定的页面在访问之前先从过滤器走一趟。

    “漏斗”的图片搜索结果

    2、过滤器相关的API

    Servlet API中,与过滤器有关的API共有三个接口,分别是:
    • Filter
    • FilterChain (在Filter中init方法作为参数)
    • FilterConfig (在Filter中doFilter方法作为参数)

    Filter接口
    Filter接口是我们自定义的过滤器类必须要实现的接口,该接口有三个方法:
    • init(FilterConfig filterConfig)
    • 该方法是对Filter对象进行初始化的方法,仅在容器初始化Filter对象结束后被调用一次,其中FilterConfig可以获取初始化参数

    • doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    • 该方法是Filter进行过滤操作的方法,是最重要的方法。我们自定义的过滤器类都要实现该方法。
    • 方法体中可以对请求和响应进行预处理,FilterChain则可以将处理后的请求响应传递到过滤链上的下一个资源

    • destroy()
    • 该方法在容器销毁过滤器对象之前被调用

    可以看到,其他两个接口是分别作为参数在Filter接口的方法中进行使用。它们的作用在于:

    FilterConfig接口
    该接口类型作为Filter接口中init方法的参数使用,这个接口有一个常用方法:
    • getInitParameter(String name)
    • 该方法用来获取过滤器的初始化参数,这个初始化参数在web.xml中进行配置,方式和Servlet初始化参数类似

    FilterChain接口
    该接口类型作为Filter接口中doFilter方法的参数使用,这个接口有一个方法:
    • doFilter(ServletRequest request, ServletResponse response)
    • 该方法可以将当前请求和相应传递到过滤链上的下一个资源,可能是下个过滤器,也可能是目标资源

    3、示例:过滤器限制页面访问时间

    实现这样的功能,某个页面,在规定的时间内才能访问,否则跳转到通知页面,告知未到开放时间,暂时无法访问。

    可以通过修改系统的时间,来完成过滤器的效果测试:

    3.1 创建jsp页面

    创建四个jsp页面:index、login、home和notice,文件放置目录结构如下:

    3.2 自定义过滤器

    自定义过滤器,读取初始参数配置,并判断是否符合要求,根据需要进行页面跳转:
    public class TimeFilter implements Filter { 
        private int start = 0;
        private int end = 24;
    
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("TimeFilter初始化,开始抓取初始化参数");
            start = Integer.parseInt(filterConfig.getInitParameter("start"));
            end = Integer.parseInt(filterConfig.getInitParameter("end"));
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("TimeFilter过滤");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            int curHour = calendar.get(Calendar.HOUR_OF_DAY);
            if (curHour >= end || curHour < start) {
                request.setAttribute("start", start);
                request.setAttribute("end", end);
                request.getRequestDispatcher("/WEB-INF/notice.jsp").forward(request, response);
            }
            
            chain.doFilter(request, response);
        }
    
        public void destroy() {
            System.out.println("TimeFilter爆炸");
        }
    }

    3.3 配置web.xml和初始化参数

    在web.xml中配置过滤器的具体类,以及过滤的资源和过滤器初始化的参数:
    <filter>
        <filter-name>timeFilter</filter-name>
        <filter-class>com.zker.TimeFilter</filter-class>
        <init-param>
            <param-name>start</param-name>
            <param-value>15</param-value>
        </init-param>
        <init-param>
            <param-name>end</param-name>
            <param-value>22</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>timeFilter</filter-name>
        <url-pattern>/limit/*</url-pattern>
    </filter-mapping>

    4、Filter使用总结和配置说明

    • 首先要实现Filter接口
    • 自定义的过滤方法写在doFilter方法体中,最后并通过形参 FilterChain 的 doFilter(request, response) 方法传递请求和响应
    • 然后要在web.xml中进行配置,包括过滤器的具体类,过滤文件,初始参数等

    关于配置文件的部分说明:
    • <filter>  定义Filter的具体类
    • <init-param>  定义初始化参数
    • <filter-mapping>  定义过滤器的限制目录

    在<filter-mapping>中实际上还可以通过 <dispatcher> 配置请求方式的过滤:
    <filter-mapping>
        <filter-name>timeFilter</filter-name>
        <url-pattern>/limit/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

    <dispatcher>配置表示哪些请求传递方式到如上的/limit/*时需要被过滤,默认不写的话为REQUEST
    (假如我只写了REQUEST,而没写FORWARD,那么通过转发方式到达的/limit/*的资源,就不会被过滤)


  • 相关阅读:
    【C++ STL】List
    【C++ STL】Deques
    【C++ STL】Vector
    【C++ STL】容器概要
    linux shell读取配置文件
    【C++对象模型】第六章 执行期语意学
    【C++对象模型】第五章 构造、解构、拷贝 语意学
    【C++对象模型】第四章 Function 语意学
    【C++对象模型】第三章 Data语义学
    [翻译]解读CSS中的长度单位
  • 原文地址:https://www.cnblogs.com/deng-cc/p/7462923.html
Copyright © 2011-2022 走看看