过滤器Filter

过滤器Filter

简介

Filter也属于Servlet规范,和Servlet的理解是一样的,不过功能不同

利用Filter, 在请求发送过来的时候,请求不会直接发给客户端,而是会被Filter拦截,当filter放行时,请求才会发送到服务器

同理,在相应发送到客户端时,相应不会直接发送到客户端,而是会被filter拦截,当filter放行时,相应才会发送到客户端

Filter 开发步骤

和Servlet类似

  1. 新建类实现Filter接口,然后实现其中的三个方法:init,doFilter, destroy

  2. 配置Filter,可以使用注解@webFilter(), 也可以在xml文件中配置: ,

// 这是过滤器类
package Fitler;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * @ClassName : filterDemo01
 * @Author : YuYun
 * @Date : 2022-04-18 11:13:40
 * @Description :这是过滤器类
 */
// 表示拦截放给demoFilter.do的请求,其他的他不会拦截
@WebFilter("/demoFilter.do")
public class filterDemo01 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("拦截器初始化。。。。。");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("请求发到拦截器》。。。");
        // 放行请求
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("相应发送到拦截器.........");
    }

    @Override
    public void destroy() {

    }
}

这是demoFilter.do

package Controller;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/demoFilter.do")
public class DemoFilter extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo01.....");
        req.getRequestDispatcher("demo02.do").forward(req, resp);
    }
}

这是demo02.do

package Controller;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ClassName : Demo02
 * @Author : YuYun
 * @Date : 2022-04-18 11:15:49
 * @Description :
 */
@WebServlet("/demo02.do")
public class Demo02 extends HttpServlet {
    @Override
    public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是Demo02");
        resp.sendRedirect("succ.html");
    }
}

这是succ.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>这是succ.html页面</title>
</head>
<body>
  <h1> 这是succ 页面</h1>
</body>
</html>

运行结果:

拦截器初始化。。。。。
请求发到拦截器》。。。
demo01.....
这是Demo02
相应发送到拦截器.........

在这里插入图片描述

过滤器链(filterChain)

在这里插入图片描述

这三个过滤器就是一个过滤器链,在实际开发中,这些过滤器的作用都是不一样的,扮演的角色也不同

上图的打印顺序是:

A, B, C demo03, service, C2, B2, A2

过滤顺序说明:如果使用注解,那么过滤的顺序就是类名的字符串顺序

如果使用xml文件配置,那么过滤的顺序就是在xml文件里边配置的顺序

这是Demo03.do:

package Controller;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ClassName : Demo03
 * @Author : YuYun
 * @Date : 2022-04-18 11:48:43
 * @Description :
 */
@WebServlet("/demo03.do")
public class Demo03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是demo03.......");
    }
}

这是A过滤器:

package Fitler;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * @ClassName : filterA
 * @Author : YuYun
 * @Date : 2022-04-18 11:49:26
 * @Description :
 */
@WebFilter("/demo03.do")
public class filterA 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("A");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("A2");
    }

    @Override
    public void destroy() {

    }
}

这是过滤器B:

package Fitler;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * @ClassName : filterB
 * @Author : YuYun
 * @Date : 2022-04-18 11:50:15
 * @Description :
 */
@WebFilter("/demo03.do")
public class filterB 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("B");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("B2");
    }

    @Override
    public void destroy() {

    }
}

这是过滤器c:

package Fitler;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * @ClassName : filterC
 * @Author : YuYun
 * @Date : 2022-04-18 11:51:02
 * @Description :
 */
@WebFilter("/demo03.do")
public class filterC 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("C");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("C2");
    }

    @Override
    public void destroy() {

    }
}

过滤器的作用:

通常,事务的管理要应用在service层上边,所以,我们通常利用filter层来进行事务的管理,让事务前置。另外修改编码格式的操作通常也会放在filter层上边

Filter生命周期(摘录自尚硅谷笔记)

和Servlet生命周期类比,Filter生命周期的关键区别是:在Web应用启动时创建对象

生命周期阶段执行时机执行次数
创建对象Web应用启动时一次
初始化创建对象后一次
拦截请求接收到匹配的请求多次
销毁Web应用卸载前一次

过滤器匹配规则

本节要探讨的是在filter-mapping中如何将Filter同它要拦截的资源关联起来。

精确匹配

指定被拦截资源的完整路径:

<!-- 配置Filter要拦截的目标资源 -->
<filter-mapping>
    <!-- 指定这个mapping对应的Filter名称 -->
    <filter-name>Target01Filter</filter-name>

    <!-- 通过请求地址模式来设置要拦截的资源 -->
    <url-pattern>/Target01Servlet</url-pattern>
</filter-mapping>

模糊匹配

相比较精确匹配,使用模糊匹配可以让我们创建一个Filter就能够覆盖很多目标资源,不必专门为每一个目标资源都创建Filter,提高开发效率。

前杠后星

在我们配置了url-pattern为/user/*之后,请求地址只要是/user开头的那么就会被匹配。

<filter-mapping>
    <filter-name>Target02Filter</filter-name>

    <!-- 模糊匹配:前杠后星 -->
    <!--
        /user/Target02Servlet
        /user/Target03Servlet
        /user/Target04Servlet
    -->
    <url-pattern>/user/*</url-pattern>
</filter-mapping>

极端情况:/*匹配所有请求

前星后缀

下面我们使用png图片来测试后缀拦截的效果,并不是只能拦截png扩展名。

创建一组img标签

    <img th:src="@{/./images/img017.png}"/><br/>
    <img th:src="@{/./images/img018.png}"/><br/>
    <img th:src="@{/./images/img019.png}"/><br/>
    <img th:src="@{/./images/img020.png}"/><br/>
    <img th:src="@{/./images/img024.png}"/><br/>
    <img th:src="@{/./images/img025.png}"/><br/>

创建Filter

<filter>
    <filter-name>Target04Filter</filter-name>
    <filter-class>com.atguigu.filter.filter.Target04Filter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Target04Filter</filter-name>
    <url-pattern>*.png</url-pattern>
</filter-mapping>

前杠后缀,星号在中间

配置方式如下:

<url-pattern>/*.png</url-pattern>

按照这个配置启动Web应用时会抛出异常:

java.lang.IllegalArgumentException: Invalid /*.png in filter mapping

**结论:这么配是*不允许*的!

匹配Servlet名称

<filter-mapping>
    <filter-name>Target05Filter</filter-name>

    <!-- 根据Servlet名称匹配 -->
    <servlet-name>Target01Servlet</servlet-name>
</filter-mapping>
>

前杠后缀,星号在中间

配置方式如下:

<url-pattern>/*.png</url-pattern>

按照这个配置启动Web应用时会抛出异常:

java.lang.IllegalArgumentException: Invalid /*.png in filter mapping

**结论:这么配是*不允许*的!

匹配Servlet名称

<filter-mapping>
    <filter-name>Target05Filter</filter-name>

    <!-- 根据Servlet名称匹配 -->
    <servlet-name>Target01Servlet</servlet-name>
</filter-mapping>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值