JavaWeb三大组件 —— Filter 过滤器

目录
    1、过滤器的生命周期方法
    2、FilterConfig
    3、FilterChain
    4、多个过滤器执行顺序
    5、四种拦截方式
    6、第一个过滤器
    7、过滤器的应用场景

过滤器(Filter)
    概述:过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。
        当用户请求某个Servlet时,会先执行部署在这个请求上的过滤器Filter,
        如果Filter"放行",那么会继续往下执行用户请求的Servlet;
        如果Filter"不放行",那么就不会执行用户请求的Servlet。
        Filter和Servlet一样都是单例的。

1、过滤器的生命周期方法(类似Servlet的生命周期方法)
    init(FilterConfig):出生之后马上调用
    doFilter(ServletRequest req,ServletResponse res,FilterChain chain):过滤方法。符合条件,放行;不符合,拦下。
    destroy():销毁之前调用

2、FilterConfig
    Filter接口中的init()方法的参数类型为FilterConfig类型。它的功能与ServletConfig相似,与web.xml文件中的配置信息对应。
    下面是FilterConfig的功能介绍:
        String getFilterName():获取Filter的配置名称;与<filter-name>元素对应;
        String getInitParameter(String name):获取Filter的初始化配置,与<init-param>元素对应;
        Enumeration getInitParameterNames():获取所有初始化参数的名称。
        ServletContext getServletContext():获取ServletContext的方法;

3、FilterChain
    过滤器的doFilter()方法的参数中有一个类型为FilterChain的参数,它只有一个方法:doFilter(ServletRequest,ServletResponse)。
    FilterChain的doFilter()方法表示当前过滤器放行,让当前请求继续往下走,可能会有下个过滤器再次过滤,也可能直接走到目标资源。
    一个目标资源上,可以部署了多个过滤器,按照web.xml的顺序从上到下依次过滤。

4、多个过滤器执行顺序
    一个目标资源可以指定多个过滤器,过滤器的执行顺序是在web.xml文件中的部署顺序(从上往下的顺序),谁在前面谁就先做过滤。

5、四种拦截方式
    JavaWeb过滤器有四种拦截方式,分别是:REQUEST、FORWARD、INCLUDE、ERROR
        REQUEST:直接访问目标资源时执行过滤器。(默认)
            包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;
        FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、<jsp:forward>标签都是转发访问;
        INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、<jsp:include>标签都是包含访问;
        ERROR:当目标资源在web.xml中配置为<error-page>中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。
    可以在<filter-mapping>中添加0~n个<dispatcher>子元素,来说明当前访问的拦截方式。
        <filter-mapping>
            <filter-name>myfilter</filter-name>
            <url-pattern>/b.jsp</url-pattern>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>INCLUDE</dispatcher>
            <dispatcher>ERROR</dispatcher>
        </filter-mapping>
    其实最为常用的就是REQUEST和FORWARD两种拦截方式。

    我们来做个测试,写一个过滤器使用默认拦截方式,指定过滤的资源为b.jsp,然后我们在浏览器中直接访问b.jsp,你会发现过滤器执行了!
    但是,当我们在a.jsp中转发request.getRequestDispathcer("/b.jsp").forward(request,response)时,就不会再执行过滤器了!
    也就是说,默认情况下,只能直接访问目标资源才会执行过滤器,而forward执行目标资源,不会执行过滤器!因为默认是REQUEST方式。
======================================
6、第一个过滤器
    其实过滤器与Servlet很相似。写过滤器就是写一个类,实现Filter接口。
        public class HelloFilter implements Filter {
            public void init (FilterConfig filterConfig) throws ServletException {
                //出生之后调用
            }
            public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
                System.out.println("HelloFilter...");
            }
            public void destroy () {
                //Tomcat销毁过滤器之前调用
            }
        }
    第二步也与Servlet一样,在web.xml文件中部署Filter:
        <filter>
            <filter-name>helloFilter</filter-name>
            <filter-class>cn.itcast.filter.HelloFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>helloFilter</filter-name>
            <url-pattern>/index.jsp </url-pattern>
        </filter-mapping>
    OK了,现在可以尝试去访问index.jsp页面了,看看是什么效果!
    当用户访问index.jsp页面时,会执行HelloFilter的doFilter()方法!在我们的示例中,index.jsp页面是不会被执行的,
    如果想执行index.jsp页面,那么我们需要放行!
   public void doFilter(ServletRequest request, ServletResponse response,
         FilterChain chain) throws IOException, ServletException {
      System.out.println("filter start...");
      chain.doFilter(request, response); //放行!
      System.out.println("filter end...");
   }
    有很多同学总是错误的认为,一个请求在给客户端输出之后就算是结束了,这是不对的!其实很多事情都需要在给客户端响应之后才能完成!

7、过滤器的应用场景
    执行目标资源之前做预处理工作。例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;
    通过条件判断是否放行。例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;
    在目标资源执行后,做一些后续的特殊处理工作。例如把目标资源输出的数据进行处理 ;

8、设置目标资源
    在web.xml文件中部署Filter时,可以通过"*"来执行目标资源:
        <filter-mapping>
            <filter-name>myfilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

    这一特性与Servlet完全相同!通过这一特性,我们可以在用户访问敏感资源时,执行过滤器,
    例如:<url-pattern>/admin/*<url-pattern>,可以把所有管理员才能访问的资源放到/admin路径下,这时可以通过过滤器来校验用户身份。
    还可以为<filter-mapping>指定目标资源为某个Servlet,例如:
        <servlet>
            <servlet-name>myservlet</servlet-name>
            <servlet-class>cn.itcast.servlet.MyServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>myservlet</servlet-name>
            <url-pattern>/abc</url-pattern>
        </servlet-mapping>
        <filter>
            <filter-name>myfilter</filter-name>
            <filter-class>cn.itcast.filter.MyFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>myfilter</filter-name>
            <servlet-name>myservlet</servlet-name>
        </filter-mapping>
  当用户访问http://localhost:8080/filtertest/abc时,会执行名字为myservlet的Servlet,这时会执行myfilter过滤器。


猜你喜欢

转载自blog.csdn.net/weixin_42472048/article/details/82946537