【JavaWeb】Web组件之Filter详细

本文介绍Web三大组件:Servlet、Filter、Listener中的Filter组件,并附上两个学习案例。



Filter:过滤器

1.概念

生活中的过滤器:净水器,空气净化器,土匪…

在这里插入图片描述
web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。

过滤器的作用:

  • 一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤…

2.Filter快速入门

实现一个过滤器的步骤:

  • 1.定义一个类,实现接口Filter;
  • 2.复写接口里的方法;
  • 3.配置过滤器拦截路径,有两种方式:web.xml配置或注解配置;

代码实现:

FilterDemo1.java

/**
 * 过滤器快速入门程序
 */
@WebFilter(urlPatterns = "/*") //访问所有资源之前,都会执行该过滤器
public class FilterDemo1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("FilterDemo1被执行了....");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

ServletDemo1.java

@WebServlet(name = "ServletDemo1", urlPatterns = "/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("访问到了ServletDemo1...");
    }
}

访问ServletDemo1,

在这里插入图片描述
控制台打印:

在这里插入图片描述

3.过滤器细节

3.1 web.xml配置

可以在web.xml中配置过滤器:

在这里插入图片描述

例如,FilterDemo1在web.xml中配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--配置过滤器-->
    <filter>
        <!--过滤器名称-->
        <filter-name>demo1</filter-name>
        <!--过滤器所在类-->
        <filter-class>com.dong.web.filter.FilterDemo1</filter-class>
    </filter>
    <!--映射-->
    <filter-mapping>
        <filter-name>demo1</filter-name>
        <!-- 拦截路径 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

3.2 过滤器执行流程

在访问有过滤器拦截的资源时,程序流程是:

  • 1.执行过滤器
  • 2.访问放行后的资源
  • 3.访问资源回来(进行响应时),执行过滤器放行代码下边的代码

例子:

FilterDemo2.java

@WebFilter(filterName = "FilterDemo2", urlPatterns = "/*")
public class FilterDemo2 implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //对request对象请求消息增强
        System.out.println("FilterDemo2执行了...");
        //放行
        chain.doFilter(req, resp);
        //对response对象的响应消息增强
        System.out.println("FilterDemo2回来了");
    }

    public void init(FilterConfig config) throws ServletException {

    }

    public void destroy() {
    }
}

将过滤器换成FilterDemo2,再次访问ServletDemo1:

在这里插入图片描述

控制台打印:

在这里插入图片描述

3.3 过滤器生命周期方法

过滤器生命周期方法即Filter接口中三个的方法:

  • 1.init方法:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。多用于加载资源
  • 2.doFilter方法:每一次请求被拦截资源时,会执行。可以执行多次
  • 3.destroy方法:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。多用于释放资源

例子:

FilterDemo3.java

@WebFilter(filterName = "FilterDemo3", urlPatterns = "/*")
public class FilterDemo3 implements Filter {

    /**
     * 每一次请求资源被拦截时,会执行doFilter方法。可以执行多次
     * @param req
     * @param resp
     * @param chain
     * @throws ServletException
     * @throws IOException
     */
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("doFilter...");
        //放行
        chain.doFilter(req, resp);

    }

    /**
     * 在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次,用于加载资源。
     * @param config
     * @throws ServletException
     */
    public void init(FilterConfig config) throws ServletException {
        System.out.println("init...");
    }

    /**
     * 在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。
     * 只执行一次,一般用于释放资源。
     */
    public void destroy() {
        System.out.println("destroy...");
    }

}

将过滤器换成FilterDemo3,再次访问ServletDemo1,然后关闭服务器:

在这里插入图片描述
控制台打印:

在这里插入图片描述

3.4 过滤器配置详解

使用@WebFilter注解

1.拦截路径urlPatterns配置:
  • 拦截具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行;
  • 拦截目录: /user/* 访问/user下的所有资源时,过滤器都会被执行;
  • 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行;
  • 拦截所有资源:/* 访问任何资源时,过滤器都会被执行;

例子:

仅演示配置拦截目录。

FilterDemo4.java

@WebFilter("/user/*")   //拦截目录: /user/* 访问/user下的所有资源时,过滤器都会被执行
public class FilterDemo4 implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FilterDemo4...");
        //放行
        chain.doFilter(req, resp);

    }

    public void init(FilterConfig config) throws ServletException {

    }

    public void destroy() {
    }
}

/user 路径下的两个Servlet资源:

ServletDemo1.java

@WebServlet(name = "ServletDemo1", urlPatterns = "/user/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("访问到了ServletDemo1...");
    }
}

ServletDemo2.java

@WebServlet(name = "ServletDemo2", urlPatterns = "/user/ServletDemo2")
public class ServletDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("访问到了ServletDemo2...");
    }
}

浏览器分别访问ServletDemo1、ServletDemo2,

在这里插入图片描述


在这里插入图片描述

控制台打印:

在这里插入图片描述

2.拦截方式配置:资源被访问的方式

注解配置:

@WebFilter注解中设置dispatcherTypes属性

属性值有:

  • REQUEST:默认值。浏览器直接请求资源
  • FORWARD:以请求转发访问资源的方式
  • INCLUDE:请求包含访问资源方式
  • ERROR:错误跳转资源
  • ASYNC:异步访问资源

例子:

FilterDemo5.java

//浏览器直接请求index.jsp资源时,该过滤器会被执行
//@WebFilter(urlPatterns="/index.jsp",dispatcherTypes = DispatcherType.REQUEST)

//只有转发访问index.jsp时,该过滤器才会被执行
//@WebFilter(urlPatterns="/index.jsp",dispatcherTypes = DispatcherType.FORWARD)

//浏览器直接请求index.jsp或者转发访问index.jsp。该过滤器才会被执行
@WebFilter(urlPatterns="/index.jsp",dispatcherTypes ={ DispatcherType.FORWARD,DispatcherType.REQUEST})
public class FilterDemo5 implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FilterDemo5...");
        //放行
        chain.doFilter(req, resp);

    }

    public void init(FilterConfig config) throws ServletException {

    }

    public void destroy() {
    }
}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  index.jsp....
  <%
    System.out.println("index.jsp....");
  %>
  </body>
</html>

ServletDemo2.java

@WebServlet(name = "ServletDemo2", urlPatterns = "/ServletDemo2")
public class ServletDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("访问到了ServletDemo2...");

        //转发到index.jsp
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }
}

浏览器直接请求或者转发访问index.jsp资源

直接请求:

在这里插入图片描述
控制台打印:

在这里插入图片描述
转发访问index.jsp:

在这里插入图片描述

控制台打印:

在这里插入图片描述
web.xml配置

在web.xml文件配置过滤器标签内,设置标签即可。

<!--配置过滤器-->
<filter>
    <!--过滤器名称-->
    <filter-name>demo5</filter-name>
    <!--过滤器所在类-->
    <filter-class>com.dong.web.filter.FilterDemo5</filter-class>
</filter>
<!--映射-->
<filter-mapping>
    <filter-name>demo5</filter-name>
    <!-- 拦截路径 -->
    <url-pattern>/index.jsp</url-pattern>
    <!--配置资源被访问的方式-->
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

3.5 过滤器链(配置多个过滤器)

多个过滤器,如果有两个过滤器,过滤器1和过滤器2,执行方式为:

  1. 执行过滤器1
  2. 过滤器2
  3. 执行访问资源
  4. 过滤器2
  5. 过滤器1

过滤器执行先后顺序问题

1.注解配置方式:按照过滤器类名的字符串比较规则比较,值小的先执行;

如:AFilter 和 BFilter,AFilter就先执行了 ,因为A的码值小于B的码值。


2.web.xml配置: 标签谁定义在上边,谁先执行;

例子:

有两个过滤器,FilterDemoA和FilterDemoB

FilterDemoA.java

@WebFilter(filterName = "FilterDemoA", urlPatterns = "/*")
public class FilterDemoA implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FilterDemoA执行了...");

        //放行
        chain.doFilter(req, resp);

        System.out.println("FilterDemoA回来了...");
    }

    public void init(FilterConfig config) throws ServletException {

    }

    public void destroy() {
    }
}

FilterDemoB.java

@WebFilter(filterName = "FilterDemoB", urlPatterns = "/*")
public class FilterDemoB implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FilterDemoB执行了...");

        //放行
        chain.doFilter(req, resp);

        System.out.println("FilterDemoB回来了...");
    }

    public void init(FilterConfig config) throws ServletException {

    }

    public void destroy() {
    }
}

浏览器访问index.jsp资源:

在这里插入图片描述
控制台打印:

在这里插入图片描述

过滤器执行先后顺序:因为类名FilterDemoA和FilterDemoB字符串比较,FilterDemoA值小。

以上就是Filter细节了,基本全面。下一篇,Filter的应用场景下的练习。


推荐阅读:
Filter案例:登录验证、敏感词汇过滤.


欢迎点赞评论,指出不足,笔者由衷感谢哦!~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值