【JavaWeb学习笔记】过滤器

JavaWeb三大组件:
    Servlet、Listener、Filter
    都需要在web.xml中进行配置,Listener中的两个感知监听器不需要配置。


——过滤器概述

    过滤器是JavaWeb的三大组件之一,它与Servlet很相似,不过过滤器是用来拦截请求的,而不是处理请求的。

    当用户请求某个Servlet或其他资源(JSP、css、html)时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继续执行用户请求的资源,如果Filter“不放行”,那么就不会执行用户请求的资源。

    其实可以这么理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定,可以理解为,Filter来决定是否调用Servlet,当执行完成Servlet的代码后,还会执行FilterChain中doFilter()方法后面的代码。


——编写一个过滤器

Filter是单例的。

1、编写一个类,并且实现Filter接口
 

import java.io.IOException;

 

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

 

/**

 * 编写过滤器

 *  1、写一个类,并且实现Filter接口

 *  2、在web.xml中进行相关配置

 * 

 * @author 31067

 * 

 */

public class AFilter implements Filter {

    /**

     * 在销毁之前执行,用来对非内存资源进行释放

     */

    @Override

    public void destroy() {

        System.out.println("销毁");

    }

 

    /**

     * 每次过滤时都会执行

     */

    @Override

    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException {

        System.out.println("拦截");

        chain.doFilter(request, response);

        System.out.println("放行了");

    }
 

    /**

     * 在Filter创建后马上调用,用来做初始化操作

     */

    @Override

    public void init(FilterConfig arg0) throws ServletException {

        System.out.println("出生");

    }

}

2、在web.xml文件中进行配置

    <filter>
        <filter-name>xxx</filter-name>
        <filter-class>com.wyc.web.filter.AFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>xxx</filter-name>
        <url-pattern>/*</url-pattern>    //通常会使用通配符进行url-pattern的配置  /web/*
    </filter-mapping> 



——Filter的生命周期

1、Filter接口生命周期方法:

    *   void init(FilterConfig config)
        在服务器启动时会创建Filter的实例对象,并且每个类型的Filter只会创建一个实例对象,也就是说Filter是单例的。
        在创建完Filter实例后,会马上调用init()方法完成初始化操作,这个方法只会被执行一次。

    *   void destory()
        服务器会在创建Filter对象之后,把Filter放到内存中一直使用,通常不会销毁它,一般会在服务器关闭时销毁Filter对象。
        在销毁Filter对象之前,服务器会调用Filter对象的destory()方法。

    *   void doFilter(ServletRequest , ServletResponse , FilterChain)
        这个方法会在用户每次访问“目标资源<url-pattern>/index.jsp</url-pattern>”时执行。
        如果需要“放行”,那么需要调用FilterChain对象的doFilter(ServletRequest, ServletResponse)方法,如果不调用该方法,则无法请求目标资源。 



2、生命周期方法中的参数

    FilterConfig:
        *   获取初始化参数:getInitParameter();
        *   获取所有初始化参数的名称:Enumeration getInitParameterNames()。
        *   获取过滤器名称:getFilterName();
        *   获取application:getServletContext();(获取当前上下文对象)

    FilterChain:
        *   doFilter(ServletRequest, ServletResponse)
            执行“放行”功能,使请求可以访问到资源。
            相当于调用了请求Servlet的Service方法。
            如果当前过滤器是最后一个过滤器,那么调用chain.doFilter()方法表示执行目标资源,如果不是最后一个过滤器,那么chain.doFilter()表示执行下一个过滤器的doFilter()方法。

    面试:Filter接口的doFilter()方法和FilterChain的doFilter()方法有什么区别?

 

——过滤器的四种拦截方式 

拦截方式:
    *   请求:DISPATCHER
    *   转发:FORWARD
    *   包含:INCLUDE
    *   错误:ERROR

    如果不写,则默认<dispatcher>REQUEST</dispatcher>,如果只写一种,则默认拦截方式就不存在了。

拦截方式需要在<filter-mapping>中进行配置:

    <filter-mapping>

        <filter-name>BFilter</filter-name>

        <url-pattern>/*</url-pattern>

        <dispatcher>REQUEST</dispatcher>    // 默认拦截方式

        <dispatcher>FORWARD</dispatcher>

        <dispatcher>INCLUDE</dispatcher>

        <dispatcher>ERROR</dispatcher>

    </filter-mapping>


——过滤器的执行顺序


<filter-mapping>中的配置执行顺序决定了过滤器的执行顺序。

    先配置先执行。
    XML配置如下:
    <web-app>

        <filter>

            <filter-name>AFilter</filter-name>

            <filter-class>com.wyc.web.filter.AFilter</filter-class>

        </filter>

        <filter-mapping>

            <filter-name>AFilter</filter-name>

            <url-pattern>/*</url-pattern>

        </filter-mapping>

 

        <filter>

            <filter-name>BFilter</filter-name>

            <filter-class>com.wyc.web.filter.BFilter</filter-class>

        </filter>

        <filter-mapping>

            <filter-name>BFilter</filter-name>

            <url-pattern>/*</url-pattern>

        </filter-mapping>
    </web-app> 


    执行效果如下:(与栈相似,当chain的doFilter()方法执行完毕后,还会继续执行剩余代码)
        AFilter...start

        BFilter...start

        index.jsp

        BFilter...end

        AFilter...end


——Filter的应用场景

1、执行目标资源之前做预处理工作,例如设置编码,这种操作通常都会放行,只是在目标资源执行之前做一些准备工作。
    几乎在所有的Servlet中都需要写:request.setCharacterEncoding();,这就可以把代码放到过滤器中。

2、通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否被禁用。

3、在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理。
    也称为回程拦截。


——Filter设置目标资源

在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>com.wyc.servlet.MyServlet</servlet-class>

    </servlet>

    <servlet-mapping>

        <servlet-name>MyServlet</servlet-name>

        <url-pattern>/MyServlet</url-pattern>

    </servlet-mapping>

 

    <filter>

        <filter-name>MyFilter</filter-name>

        <filter-class>com.wyc.filter.MyFilter</filter-class>

    </filter>

    <filter-mapping>

        <filter-name>MyFilger</filter-name>

        <servlet-name>MyServlet</servlet-name>    // 访问指定的Servlet

    </filter-mapping>

    当用户访问:localhost:8080/FilterDemo/MyServlet时,会执行名称为MyServlet的Servlet,这时会执行绑定的过滤器。 


    <filter-mapping>中可以写以下四种标签:
        <filter-name>
        <url-pattern>
        <dispatcher>
        <servlet-name>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值