Java Web-Filter
Filter
在 Java Web 开发中,Filter(过滤器)是 Servlet 规范中的一个重要组件,它可以对客户端与服务器之间的请求和响应进行预处理和后处理。以下从多个方面详细介绍 Java Web 中的 Filter:
一、概念和作用
- 概念:Filter 是一种特殊的 Servlet 组件,它可以在请求到达目标资源(如 Servlet、JSP 等)之前或响应返回客户端之前对请求和响应进行拦截和处理。
- 作用
- 权限验证:检查用户是否具有访问某个资源的权限,例如在用户未登录时阻止其访问需要登录才能访问的页面。
- 字符编码处理:统一设置请求和响应的字符编码,避免出现乱码问题。
- 日志记录:记录每个请求的详细信息,如请求的 URL、参数、请求时间等,方便后续的系统监控和问题排查。
- 数据过滤和验证:对请求参数进行过滤和验证,防止恶意输入或不符合要求的数据进入系统。
二、工作原理
当客户端发送请求到服务器时,请求首先会经过一系列的 Filter。每个 Filter 可以对请求进行检查和修改,然后将请求传递给下一个 Filter 或目标资源。当目标资源处理完请求后,响应会按照相反的顺序再次经过这些 Filter,每个 Filter 可以对响应进行后处理,最后将响应返回给客户端。
实现步骤
1. 创建 Filter 类
Filter 类需要实现 javax.servlet.Filter 接口,并重写其中的三个方法:init()、doFilter() 和 destroy()。
import javax.servlet.*;
import java.io.IOException;public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化方法,在 Filter 实例创建后调用,可用于初始化资源System.out.println("MyFilter 初始化");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 过滤方法,对请求和响应进行处理System.out.println("MyFilter 开始处理请求");// 设置请求和响应的字符编码request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");// 将请求和响应传递给下一个 Filter 或目标资源chain.doFilter(request, response);System.out.println("MyFilter 处理响应结束");}@Overridepublic void destroy() {// 销毁方法,在 Filter 实例销毁前调用,可用于释放资源System.out.println("MyFilter 销毁");}
}
2. 配置 Filter
有两种常见的配置方式:使用 web.xml 配置文件或使用注解。
使用 web.xml 配置
<filter><filter-name>MyFilter</filter-name><filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping><filter-name>MyFilter</filter-name><!-- 过滤所有请求 --><url-pattern>/*</url-pattern>
</filter-mapping>
用注解配置
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {// 省略方法实现
}
三、Filter 链
在 Java Web 开发中,过滤器链(Filter Chain)是一个重要的概念,它允许多个过滤器(Filter)按照特定顺序对请求和响应进行处理。下面将从过滤器链的概念、工作原理、配置方式、执行顺序以及应用场景等方面进行详细解释。
概念
过滤器链是由多个过滤器组成的一个有序列表。当客户端向服务器发送请求时,请求会依次经过过滤器链中的每个过滤器,每个过滤器可以对请求进行预处理,如验证用户身份、设置字符编码等。当请求到达目标资源(如 Servlet、JSP 等)并处理完成后,响应会按照相反的顺序再次经过过滤器链,每个过滤器可以对响应进行后处理,如压缩响应数据、添加响应头信息等。
工作原理
- 请求阶段:客户端发送请求到服务器,服务器接收到请求后,会根据配置的过滤器链,依次将请求传递给链中的每个过滤器。每个过滤器在接收到请求后,可以对请求进行修改或增强,然后将请求传递给下一个过滤器。如果某个过滤器决定不将请求继续传递给下一个过滤器,它可以直接返回响应给客户端,从而终止请求的处理流程。
- 响应阶段:当请求到达目标资源并处理完成后,服务器会生成响应。响应会按照与请求阶段相反的顺序经过过滤器链,每个过滤器可以对响应进行修改或增强,最后将响应返回给客户端。
配置方式
可以通过 web.xml 配置文件或注解的方式来配置过滤器链。
使用 web.xml 配置
<filter><filter-name>Filter1</filter-name><filter-class>com.example.Filter1</filter-class>
</filter>
<filter><filter-name>Filter2</filter-name><filter-class>com.example.Filter2</filter-class>
</filter>
<filter-mapping><filter-name>Filter1</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping><filter-name>Filter2</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
在上述配置中,Filter1 和 Filter2 会组成一个过滤器链,请求会先经过 Filter1,再经过 Filter2。
使用注解配置
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;@WebFilter(urlPatterns = "/*", filterName = "Filter1")
public class Filter1 implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 预处理逻辑System.out.println("Filter1: 请求预处理");chain.doFilter(request, response);// 后处理逻辑System.out.println("Filter1: 响应后处理");}
}@WebFilter(urlPatterns = "/*", filterName = "Filter2")
public class Filter2 implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 预处理逻辑System.out.println("Filter2: 请求预处理");chain.doFilter(request, response);// 后处理逻辑System.out.println("Filter2: 响应后处理");}
}
在上述代码中,Filter1 和 Filter2 都会对所有请求进行拦截,具体的执行顺序可能因 Servlet 容器而异。
执行顺序
web.xml配置:在web.xml中,<filter-mapping>标签的配置顺序决定了过滤器的执行顺序。先配置的过滤器会先执行,后配置的过滤器后执行。- 注解配置:使用注解配置时,不同的 Servlet 容器可能有不同的处理方式。有些容器会按照类名的字典序来决定过滤器的执行顺序,而有些容器可能没有明确的顺序。为了确保过滤器按照预期的顺序执行,建议使用
web.xml进行配置。
应用场景
- 身份验证和授权:可以使用多个过滤器来实现不同级别的身份验证和授权。例如,一个过滤器用于验证用户是否已登录,另一个过滤器用于验证用户是否具有访问特定资源的权限。
- 字符编码处理:可以在过滤器链中配置一个过滤器,用于统一设置请求和响应的字符编码,避免出现乱码问题。
- 日志记录:可以使用过滤器链来记录每个请求的详细信息,如请求的 URL、参数、请求时间等,方便后续的系统监控和问题排查。
- 数据过滤和验证:可以在过滤器链中配置多个过滤器,对请求参数进行过滤和验证,防止恶意输入或不符合要求的数据进入系统。
示例代码执行结果分析
假设有上述的 Filter1 和 Filter2 两个过滤器,当客户端发送一个请求时,控制台可能会输出以下信息:
Filter1: 请求预处理
Filter2: 请求预处理
(目标资源处理请求)
Filter2: 响应后处理
Filter1: 响应后处理
从输出结果可以看出,请求阶段过滤器按照 Filter1 -> Filter2 的顺序执行,响应阶段过滤器按照 Filter2 -> Filter1 的顺序执行。
通过使用过滤器链,可以将不同的功能逻辑分离到不同的过滤器中,提高代码的可维护性和可扩展性。
四、应用场景举例
登录验证 Filter
package com.itheima.web.filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;@WebFilter("/*")
public class LoginFilter implements Filter {// 未登录即可放行的资源列表,常量private static final String[] PUBLIC_URLS = {"/adminServlet","index.html", "admin.jsp", "register.jsp", "/registerServlet", "login.jsp", "/loginServlet"};@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {// 设置请求和响应的字符编码,避免中文乱码request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");HttpServletRequest req = (HttpServletRequest) request;// 获取请求的 URI 部分String uri = req.getRequestURI();// 检查是否为未登录即可放行的资源for (String u : PUBLIC_URLS) {if (uri.endsWith(u)) {// 可以放行chain.doFilter(request, response);return;}}// 到这步说明访问的资源不可以直接放行,必须登录HttpSession session = req.getSession();Object user = session.getAttribute("user");Object admin = session.getAttribute("admin");// 判断 user 或 admin 是否不为 nullif (user != null || admin != null) {// 用户或管理员已登录,放行请求chain.doFilter(request, response);} else {// 没登陆过,跳转到登录页面req.setAttribute("login_errmsg", "请登录");req.getRequestDispatcher("login.jsp").forward(request, response);}}@Overridepublic void destroy() {}
}
这个 Filter 会检查用户是否已登录,如果未登录则重定向到登录页面。
相关文章:
Java Web-Filter
Filter 在 Java Web 开发中,Filter(过滤器)是 Servlet 规范中的一个重要组件,它可以对客户端与服务器之间的请求和响应进行预处理和后处理。以下从多个方面详细介绍 Java Web 中的 Filter: 一、概念和作用 概念&…...
LeetCode 热题100 438. 找到字符串中所有字母异位词
LeetCode 热题100 | 438. 找到字符串中所有字母异位词 大家好,今天我们来解决一道经典的算法题——找到字符串中所有字母异位词。这道题在 LeetCode 上被标记为中等难度,要求我们在字符串 s 中找到所有是 p 的异位词的子串,并返回这些子串的…...
DeepSeek-R1训练时采用的GRPO算法数学原理及算法过程浅析
先来简单看下PPO和GRPO的区别: PPO:通过奖励和一个“评判者”模型(critic 模型)评估每个行为的“好坏”(价值),然后小步调整策略,确保改进稳定。 GRPO:通过让模型自己生…...
Qt基于信号量QSemaphore实现的生产者消费者模型
在 Qt 中,信号量(QSemaphore)是一种用于控制对共享资源访问的同步工具。它允许一定数量的线程同时访问共享资源,适合用于生产者-消费者模型。 代码实现 #include <QCoreApplication> #include <QThread> #include &…...
七星棋牌 6 端 200 子游戏全开源修复版源码(乐豆 + 防沉迷 + 比赛场 + 控制)
七星棋牌源码 是一款运营级的棋牌产品,覆盖 湖南、湖北、山西、江苏、贵州 等 6 大省区,支持 安卓、iOS 双端,并且 全开源。这个版本是 修复优化后的二开版本,新增了 乐豆系统、比赛场模式、防沉迷机制、AI 智能控制 等功能&#…...
CSDN博客导出设置介绍
在CSDN编辑博客时,如果想导出保存到本地,可以选择导出为Markdown或者HTML格式。其中导出为HTML时有这几种选项:jekyll site,plain html,plain text,styled html,styled html with toc。分别是什…...
_ 为什么在python中可以当变量名
在 Python 中,_(下划线)是一个有效的变量名,这主要源于 Python 的命名规则和一些特殊的使用场景。以下是为什么 _ 可以作为变量名的原因和常见用途: --- ### 1. **Python 的命名规则** Python 允许使用字母ÿ…...
使用haproxy实现MySQL服务器负载均衡
一、环境准备 主机名IP地址备注openEuler-1192.168.121.11mysql-server-1openEuler-2192.168.121.12mysql-server-2openEuler-3192.168.121.13clientRocky-1192.168.121.51haproxy 二、mysql-server配置 [rootopenEuler-1 ~]# yum install -y mariadb-server [rootopenEuler…...
音视频-WAV格式
1. WAV格式说明: 2. 格式说明: chunkId:通常是 “RIFF” 四个字节,用于标识文件类型。(wav文件格式表示)chunkSize:表示整个文件除了chunkId和chunkSize这 8 个字节外的其余部分的大小。Forma…...
apload-lab打靶场
1.提示显示所以关闭js 上传<?php phpinfo(); ?>的png形式 抓包,将png改为php 然后放包上传成功 2.提示说检查数据类型 抓包 将数据类型改成 image/jpeg 上传成功 3.提示 可以用phtml,php5,php3 4.先上传.htaccess文件࿰…...
通用查询类接口数据更新的另类实现
文章目录 一、简要概述二、java工程实现1. 定义main方法2. 测试运行3. 源码放送 一、简要概述 我们在通用查询类接口开发的另类思路中,关于接口数据的更新,提出了两种方案: 文件监听 #mermaid-svg-oJQjD6jQ8T19XlHA {font-family:"tre…...
sentinel详细使用教学
sentinel源码地址: https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D sentinel官方文档: https://sentinelguard.io/zh-cn/docs/introduction.html Sprong Cloud alibaba Sentinel文档【小例子】 : https://github.com/alibaba/spring-cl…...
python django
官网地址 https://www.djangoproject.com/ 安装 控制台输入命令 pip install django 或者可以指定版本号 pip install django3.2.4 创建项目 在控制台找个目录存放生成好的项目,输入命令 django-admin startproject demo_django 然后用pycharm打开项目可以…...
SuperMap iClient3D for WebGL 影像数据可视范围控制
在共享同一影像底图的服务场景中,如何基于用户权限体系实现差异化的数据可视范围控制?SuperMap iClient3D for WebGL提供了自定义区域影像裁剪的方法。让我们一起看看吧! 一、数据制作 对于上述视频中的地图制作,此处不做讲述&am…...
HTML元素,标签到底指的哪块部分?单双标签何时使用?
1. 标签(Tag) vs 元素(Element) 标签(Tag) 标签是 HTML 中用于定义元素的符号,用尖括号 < > 包裹。例如 <img> 是标签。元素(Element) 元素是由 标签 内容…...
OpenHarmony4.1-轻量与小型系统ubuntu开发环境
因OpenHarmony官网提供包含轻量、小型与标准系统的全量代码非常宠大,解包后大概需要70G以上硬盘空间,如要编译标准系统则需要140G以上空间。 如硬盘空间有限与只使用轻量/小型OpenHarmony系统,则可以下载并直接使用本人裁剪源码过的ubuntu硬盘…...
秒杀系统的常用架构是什么?怎么设计?
架构 秒杀系统需要单独部署,如果说放在订单服务里面,秒杀的系统压力太大了就会影响正常的用户下单。 常用架构: Redis 数据倾斜问题 第一步扣减库存时 假设现在有 10 个商品需要秒杀,正常情况下,这 10 个商品应该均…...
LabVIEW中三种PSD分析VI的区别与应用
在LabVIEW的声音与振动分析工具包中,SVFA Power Spectral Density VI、SVFA Power Spectral Density Subset VI 和 SVFA Zoom Power Spectral Density VI 均用于信号频域分析,但它们在功能、适用场景和操作逻辑上存在显著差异。以下从区别、应用场合、注…...
Python 如何实现 Markdown 记账记录转 Excel 存储
文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons:JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram,自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 ? 5 IDEA必装的插件&…...
蓝桥杯备考:动态规划入门题目之下楼梯问题
按照动态规划解题顺序,首先,我们要定义状态表示,这里根据题意f[i]就应该表示有i个台阶方案总数 第二步就是 确认状态转移方程,画图分析 所以实际上f[i] 也就是说i个台阶的方案数实际上就是第i-1个格子的方案数第i-2个格子的方案数…...
【树莓派学习】树莓派3B+的安装和环境配置
【树莓派学习】树莓派3B的安装和环境配置 文章目录 【树莓派学习】树莓派3B的安装和环境配置一、搭建Raspberry Pi树莓派运行环境1、下载树莓派镜像下载器2、配置wifi及ssh3、SSH访问树莓派1)命令行登录2)远程桌面登录3)VNC登录(推…...
算法题(83):寄包柜
审题: 需要我们对模拟柜子的数组进行插入数据和打印数据的操作 思路: 首先我们观察题目,发现可以用一个数组表示一个柜子,而数组中每个索引的位置可以看成是一个个格子。但是柜子的数据量是1e5,且格子的数据量是1e5.如…...
深入浅出MySQL:概述与体系结构解析
目录 1. 初识MySQL 1.1. 数据库 1.1.1. OLTP(联机事务处理)1.1.2. OLAP(联机分析处理) 2. SQL 2.1. 定义2.2. DQL(数据查询语言)2.3. DML(数据操纵语言)2.4. DDL(数据定…...
tin这个单词怎么记
英语单词 tin,一般用作名词,意为“罐头;锡”: tin n.锡;罐头;罐;罐头盒;(盛涂料、胶水等的)马口铁罐,白铁桶;罐装物;金属食品盒;烘焙…...
【0005】Python变量详解
如果你觉得我的文章写的不错,请关注我哟,请点赞、评论,收藏此文章,谢谢! 本文内容体系结构如下: 任何一个语言编写的程序或者项目,都需要数据的支持,没有数据的项目不能称之为一个…...
yolov8_pose模型,使用rknn在安卓RK3568上使用
最近在使用rknn的一些功能,看了看文档以及自己做的一些jni,使用上yolov8_pose的模型. 1.我们先下载一下rknn的模型功能代码,rk有自己做的一套demo 地址:GitHub - airockchip/rknn_model_zooContribute to airockchip/rknn_model_zoo development by creating an account on G…...
HTTP 协议的发展历程:从 HTTP/1.0 到 HTTP/2.0
HTTP 协议的发展历程:从 HTTP/1.0 到 HTTP/2.0 HTTP(HyperText Transfer Protocol,超文本传输协议)是 Web 的基础协议,用于客户端和服务器之间的通信。从 HTTP/1.0 到 HTTP/2.0,HTTP 协议经历了多次重大改…...
PartitionFinder2 安装与使用-bioinfomatics tools 051
1. 引言 PartitionFinder2 是目前针对大中型数据集(核苷酸、氨基酸、形态数据)最理想的分区检测和进化模型选择工具。其推演的最优进化模型结果与 jModelTest2(核苷酸)和 ProTest3(氨基酸)的结果较为接近。…...
MCP与RAG:增强大型语言模型的两种路径
引言 近年来,大型语言模型(LLM)在自然语言处理任务中展现了令人印象深刻的能力。然而,这些模型的局限性,如知识过时、生成幻觉(hallucination)等问题,促使研究人员开发了多种增强技…...
ARM 架构下 cache 一致性问题整理
本篇文章主要整理 ARM 架构下,和 Cache 一致性相关的一些知识。 本文假设读者具备一定的计算机体系结构和 Cache 相关基础知识,适合有相关背景的读者阅读 1、引言 简单介绍一下 Cache 和内存之间的关系 在使能 Cache 的情况下,CPU 每次获取数…...
