学习Java的日子 Day62 Filter过滤器

news2024/11/14 13:47:48

Day62 Filter过滤器

简介

Filter:过滤器,通过Filter可以拦截访问web资源的请求与响应操作。

Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器。他可以拦截Jsp、Servlet、 静态图片文件、静态 html文件等,从而实现一些特殊的功能。

例如:实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

服务器发送请求,通过层层过滤器,才能访问资源

在这里插入图片描述

在这里插入图片描述

创建步骤
  1. 创建过滤器类并实现Filter接口
  2. 在web.xml文件中配置Filter

javax.servlet.Filter接口中的方法介绍:

方法描述
init(FilterConfig fConfig)初始化方法
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)过滤方法
destroy()销毁方法

1.初始Filter过滤器

创建过滤器的步骤:

1.创建Java类,实现Filter接口(javax.servlet.Filter)

2.在web.xml中配置

操作

Welcome.html

导包servlet-api.jar,在web.xml中配置首页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>欢迎页面</h1>
    
<a href="ser01">向Servlet01发送一个请求</a>
    
</body>
</html>

Filter01

package com.qf.filter;

public class Filter01 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("Filter01 -- doFilter() -- 前");
        //chain过滤器链
        //注意:如果拦截后不调用doFilter(),请求将无法传到下一个过滤器或服务器里
        //放行
        filterChain.doFilter(servletRequest,servletResponse);

        System.out.println("Filter01 -- doFilter() -- 后");
    }

    @Override
    public void destroy() {

    }
}

Servlet01

package com.qf.servlet;

@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("Servlet01收到了一个请求");
    }
}

在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">

    <welcome-file-list>
        <welcome-file>Welcome.html</welcome-file>
    </welcome-file-list>

    <filter>
        <filter-name>Filter01</filter-name>
        <filter-class>com.qf.filter.Filter01</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Filter01</filter-name>
        <url-pattern>/*</url-pattern><!-- 拦截所有请求 -->
    </filter-mapping>
    
</web-app>

2.过滤器链

客户端对服务器请求之后,服务器在调用Servlet之前,会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。

过滤器链是指在一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链。

在这里插入图片描述

3.Filter的生命周期

3.1生命周期 - 单个过滤器

单个过滤器的生命周期:

​ 创建:项目启动时 – 无参构造、init()

​ 销毁:服务器正常关闭时 – destroy()

package com.qf.filter;

public class Filter01 implements Filter {

    public Filter01(){
        System.out.println("Filter01 -- Filter01()");
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        String code = filterConfig.getInitParameter("code");
        System.out.println("Filter01 -- init() -- " + code);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("Filter01 -- doFilter() -- 前");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);

        System.out.println("Filter01 -- doFilter() -- 后");
    }

    @Override
    public void destroy() {
        System.out.println("Filter01 -- destroy()");
    }
}

在web.xml配置文件中配置初始化参数信息 code-UTF-8

<?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">

    <welcome-file-list>
        <welcome-file>Welcome.html</welcome-file>
    </welcome-file-list>

    <filter>
        <filter-name>Filter01</filter-name>
        <filter-class>com.qf.filter.Filter01</filter-class>
        <init-param>
            <param-name>code</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Filter01</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

运行结果:

在这里插入图片描述

3.2 生命周期 - 多个过滤器

Filter的生命周期:

​ 创建:项目启动时 – 无参构造、init()

​ 销毁:服务器正常关闭时 – destroy()

Filter的创建顺序 – 不用关注:

​ 多线程抢资源(创建顺序无序)

Filter的调用顺序 – 关注:

​ web.xml配置 ------> 按照配置顺序

​ @WebFilter配置 --> 按照类名的字典排序

经验:一般使用web.xml配置

是单例模式

//----------- Filter01 -----------------------
public class Filter01 implements Filter {
    public Filter01() {
    	System.out.println("Filter01 - Filter01()");
    }
    public void init(FilterConfig fConfig) throws ServletException {
    	System.out.println("Filter01 - init()");
	}
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	System.out.println("Filter01执行前");
    	chain.doFilter(request, response);//放行
    	System.out.println("Filter01执行后");
	}
    
	public void destroy() { 
		System.out.println("Filter01 - destroy()");
	}
}

//----------- Filter02 -----------------------
public class Filter02 implements Filter {

	public Filter02() {
		System.out.println("Filter02 - Filter02()");
	}

	public void init(FilterConfig fConfig) throws ServletException {
		System.out.println("Filter02 - init()");
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("Filter02执行前");
		chain.doFilter(request, response);//放行
		System.out.println("Filter02执行后");
	}
	public void destroy() { 
		System.out.println("Filter02 - destroy()");
	}
}

//----------- Filter03 -----------------------
public class Filter03 implements Filter {

	public Filter03() {
		System.out.println("Filter03 - Filter03()");
	}

	public void init(FilterConfig fConfig) throws ServletException {
		System.out.println("Filter03 - init()");
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("Filter03执行前");
		chain.doFilter(request, response);//放行
		System.out.println("Filter03执行后");
	}
	public void destroy() { 
		System.out.println("Filter03 - destroy()");
	}
}

2.在web.xml配置文件中配置过滤器信息

<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">
    
    <welcome-file-list>
        <welcome-file>welcome.html</welcome-file>
    </welcome-file-list>
    
         <filter> 
             <filter-name>Filter01</filter-name> 
             <filter-class>com.qf.filter.Filter01</filter-class> 
             <init-param> 
                 <param-name>code</param-name> 
                 <param-value>UTF-8</param-value> 
             </init-param> 
         </filter> 
         <filter-mapping> 
             <filter-name>Filter01</filter-name> 
             <url-pattern>/*</url-pattern> 
         </filter-mapping> 
    
         <filter> 
             <filter-name>Filter02</filter-name> 
             <filter-class>com.qf.filter.Filter02</filter-class> 
             <init-param> 
                 <param-name>code</param-name> 
                 <param-value>UTF-8</param-value> 
             </init-param> 
         </filter> 
         <filter-mapping> 
             <filter-name>Filter02</filter-name> 
             <url-pattern>/*</url-pattern> 
         </filter-mapping> 
    
         <filter> 
             <filter-name>Filter03</filter-name> 
             <filter-class>com.qf.filter.Filter03</filter-class> 
             <init-param> 
                 <param-name>code</param-name> 
                 <param-value>UTF-8</param-value> 
             </init-param> 
         </filter> 
         <filter-mapping> 
             <filter-name>Filter03</filter-name> 
             <url-pattern>/*</url-pattern> 
         </filter-mapping> 
    
</web-app>

3.3 注解配置过滤器(简化配置)

创建顺序:创建顺序无序

执行顺序:按照类名的顺序执行

注意:一般不使用这个

@WebFilter(value="/*",initParams={@WebInitParam(name="encode",value="UTF-8")})
public class EncodeFilter implements Filter {
    ...
}

4.案例

在这里插入图片描述

4.1 案例一:编码过滤器

解决请求和响应乱码问题

package com.qf.filter;

public class CodeFilter implements Filter {
    private String code;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        //获取web.xml中该过滤器的初始化属性
         code = filterConfig.getInitParameter("code");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        servletRequest.setCharacterEncoding(code);
        servletResponse.setContentType("text/html;charset="+code);
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

   <filter>
        <filter-name>CodeFilter</filter-name>
        <filter-class>com.qf.filter.CodeFilter</filter-class>
        <init-param>
            <param-name>code</param-name><!-- 初始化参数名 -->
            <param-value>UTF-8</param-value><!-- 初始化参数值 -->
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CodeFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

4.2 案例二:登录权限过滤器

解决权限的统一控制问题,没有登录,就不能直接跳转到其他详情页面

package com.qf.filter;

public class LoginFilter implements Filter {
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {

   }

   @Override
   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

       //强转
       HttpServletRequest request= (HttpServletRequest) servletRequest;
       HttpServletResponse response= (HttpServletResponse) servletResponse;

       //获取请求地址
       String uri = request.getRequestURI();
       
       if (uri.equals("/Day19_war_exploded/")   ||
               uri.contains("register.jsp")   ||
               uri.contains("RegisterServlet")   ||
               uri.contains("welcome.html")   ||
               uri.contains("login.jsp")   ||
               uri.contains("CodeServlet")   ||
               uri.contains("LoginServlet") ){
           filterChain.doFilter(request,response);
       }else {
           //如果登录成功,会存储session凭证
           HttpSession session = request.getSession();
           String username = (String) session.getAttribute("username");
           String name = (String) session.getAttribute("name");
           String role = (String) session.getAttribute("role");

           if (username==null||name==null||role==null){//session凭证为空,不允许登录
               response.sendRedirect("login.jsp");
           }else {
               if(!role.equals("teacher") && uri.contains("GetStuListServlet")){
                   response.sendRedirect("login.jsp");
               }else{
                   filterChain.doFilter(request,response);
               }
           }
       }

   }

   @Override
   public void destroy() {

   }
}

    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>com.qf.filter.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

4.3 案例三:关键字过滤器

解决文档内的一个敏感词汇

Welcome.html,提交建议

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <a href="proposal.jsp">提交建议</a>
</body>
</html>

proposal.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    
<h1>建议页面</h1>
<form action="ProposalServlet" method="post">
    建议:<input type="text" name="info"><br>
    <input type="submit" value="提交"/>
    <input type="button" value="返回" οnclick="goIndex()"/>
</form>

<script type="text/javascript">
    function goIndex(){
        window.location = "Welcome.html";
    }
</script>
</body>
</html>

MyHttpServletRequestWrapper

请求包装类,处理敏感词

package com.qf.wrapper;

public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
    //有参构造
    public MyHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    //子类重写
    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        //把尖括号替换成字符尖括号,替换后不会认为是html里的尖括号符号
        value = value.replaceAll("<", "&lt;");
        value = value.replaceAll(">", "&gt;");
        value = value.replaceAll("傻逼", "**");

        return value;

    }
}

SensitiveWordsFilter

package com.qf.filter;

public class SensitiveWordsFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //创建请求包装类对象(注意:对象中包含了请求对象)
        MyHttpServletRequestWrapper myHttpServletRequestWrapper = new MyHttpServletRequestWrapper(request);

        //放行的是请求包装类对象
        filterChain.doFilter(myHttpServletRequestWrapper,response);

    }

    @Override
    public void destroy() {

    }
}

    <filter>
        <filter-name>SensitiveWordsFilter</filter-name>
        <filter-class>com.qf.filter.SensitiveWordsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SensitiveWordsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


运行结果:

在这里插入图片描述

在这里插入图片描述

总结

Filter
概念
理解:过滤器链
过滤器的生命周期
案例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1970484.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构——二叉树_堆

目录 一、堆的概念 二、堆的结构 三、性质 &#xff08;1&#xff09;堆的性质 &#xff08;2&#xff09;二叉树的性质 四、堆的实现 &#xff08;1&#xff09;头文件——Heap.h (2)源文件——Heap.c 1.堆的初始化 2.堆的销毁 3.向上调整算法 4.堆的插入 4.判断堆…

​人工智能薪酬排行榜:2024年哪些岗位最吃香?

近日&#xff0c;智联招聘发布了2024年二季度《中国企业招聘薪酬报告》。报告显示&#xff0c;人工智能行业平均薪酬为13594元/月&#xff0c;位居行业榜首。 同时&#xff0c;在“2024年二季度企业招聘薪酬TOP20职业”中&#xff0c;人工智能工程师以平均月薪22003元排名第一。…

口碑最好的麦克风品牌有哪些,无线领夹麦克风十大品牌推荐

​在内容丰富的自媒体世界里&#xff0c;每一个细节都可能是吸引观众的关键&#xff0c;尤其是音质。面对这么多的无线领夹麦克风&#xff0c;到底哪款更值得入手呢&#xff1f;我试用并挑选了几款性价比高的无线领夹麦克风&#xff0c;它们能够为各类视频制作提供令人印象深刻…

7.5寸电子日历

7.5英寸无线智能纸质显示屏幕办公名牌电子墨水数字显示ESL标签仓库使用

ONVIF 摄像头视频流获取 - 步骤与Python例程

1.基本流程 加入组播udp接口&#xff0c;查询子网内在线的ONVIF摄像头的设备地址&#xff1a; 设备地址形如&#xff1a;http://192.168.0.6/onvif/device_service 这一步&#xff0c;参看上一篇发文&#xff1a;[ONVIF系列 - 01] 简介 - 设备发现 - 相关工具-CSDN博客查询med…

叉车车队管理系统怎么选,满足监管要求!

在现代物流与仓储管理中&#xff0c;选择一个高效且可靠的叉车车队管理系统至关重要。一个高性能的管理系统不仅提升作业效率&#xff0c;还能保障作业安全。企业管理者在采购叉车车队管理系统前需要考虑几个关键因素&#xff1a; 1、提升管理效率&#xff1a;‌确保系统能够实…

机器学习赋能的智能光子学器件系统研究与应用

在人工智能与光子学设计融合的背景下&#xff0c;科研的边界持续扩展&#xff0c;创新成果不断涌现。从理论模型的整合到光学现象的复杂模拟&#xff0c;从数据驱动的探索到光场的智能分析&#xff0c;机器学习正以前所未有的动力推动光子学领域的革新。据调查&#xff0c;目前…

【计算机毕业设计】707高校宿舍管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

电脑数据有没有办法恢复?适用于 Windows电脑的的 14 款Windows 恢复工具

如果您在笔记本电脑上安装了 Windows 10&#xff0c;却发现文件均未复制到新系统&#xff0c;该怎么办&#xff1f;您可以在线搜索 Windows 10 恢复工具下载&#xff0c;结果会有很多。 确实&#xff0c;优秀的 Windows 恢复工具能够有效地恢复已删除的文件。问题是市场上有太…

为什么有时候银行贷款审核会查大数据信用?

在申请银行贷款时&#xff0c;不少人会疑惑为何银行会深入审查申请人的大数据信用信息。这背后&#xff0c;其实是银行风险控制与精准决策的体现。 首先&#xff0c;大数据信用信用能全面反映申请人的信用状况 它不仅仅局限于传统的征信报告&#xff0c;还涵盖了消费行为、社交…

无线麦克风可以唱歌吗?领夹麦克风十大品牌,麦克风什么牌子好

追求卓越音质与无拘无束表现力的今天&#xff0c;无线领夹麦克风已成为众多创作者、主播、演讲者以及表演艺术家的得力助手。它们不仅提供了更大的自由度和灵活性&#xff0c;还确保了声音的清晰度和传输的稳定性&#xff0c;有专业的装备才能生成高质量的视频作品&#xff0c;…

WPF中调用UWP API

最近在github上看到一个音乐播放器项目&#xff0c;dopamine(项目地址&#xff1a;GitHub - digimezzo/dopamine-windows: Audio player which tries to make organizing and listening to music as simple and pretty as possible.) 在编译时&#xff0c;提示有一个库找不到 …

免费泛域名证书申请(永久免费,不限申请次数)

免费泛域名证书&#xff08;也称为通配符SSL证书&#xff09;的申请过程通常涉及以下几个步骤。以下是一个详细的指南&#xff0c;帮助您了解如何申请免费泛域名证书&#xff1a; 一、选择合适的证书提供商 目前&#xff0c;市场上提供免费泛域名证书的服务商主要有Lets Encr…

从零开始学习网络安全渗透测试之基础入门篇——(六)网络抓包全局协议封包监听网卡模式科来wiresharkPC应用

网络抓包技术是一种用于捕获和分析网络数据包的技术手段。它能够帮助我们深入了解网络中的数据传输情况&#xff0c;对于网络故障排查、性能优化、安全监测等方面都具有重要意义。 网络抓包的工作原理通常是通过将网络接口设置为混杂模式&#xff0c;使其能够接收流经该接口的…

openEuler使用mariadb

1.安装mariadb 两者互为依赖 解决&#xff1a; 2.开机自启 3.进入数据库 数据库默认没有密码&#xff0c;直接回车进入 4.安全初始化 5.修改密码 远程用户无法登录 6.创建远程登录用户 7.创建数据库 8.赋予远程用户bbs数据库的操作权限 查看用户权限 9.使用普通账号&…

[Docker][Docker NetWork][下]详细讲解

目录 1.网络管理命令1.docker network creatre2.docker network inspect3.docker network connect4.docker network disconnect5.docker network prune6.docker network rm7.docker network ls 2.docker bridge 详解0.基本概念1.默认 bridge2.自定义 bridge3.DNS解析4.端口暴露…

45 标准库 collections 中与字典有关的类

Python 标准库中提供了很多扩展功能&#xff0c;大幅度提高了开发效率。主要介绍 collections 中 OrderedDict 类、defaultdict 类和 Counter类。 1 OrderedDict 类 Python 内置字典 dict 是无序的&#xff0c;如果需要一个可以记住元素插入顺序的字典&#xff0c;则可以使用…

大厂的风控引擎架构设计

1 架构师能力思维模型 全局思维抽象思维 2 新需求的思考路径 需求是否合理&#xff0c;是否能解决问题&#xff1f; 能划分多少个子系统&#xff1f; 每个子系统能划分多少个模块&#xff1f;这个系统需要可靠性吗&#xff0c;需要扩展能力吗&#xff1f;成本需要控制吗&a…

路径规划——广度优先搜索与深度优先搜索

路径规划——广度优先搜索与深度优先搜索 https://www.hello-algo.com/chapter_graph/graph_traversal/ 1.广度优先搜索 Breath-First-Search 在图论中也称为广度优先遍历&#xff0c;类似于树的层序遍历。 算法原理 从起始节点出发&#xff0c;首先访问它的邻近节点&…