当前位置: 首页 > article >正文

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 等)并处理完成后,响应会按照相反的顺序再次经过过滤器链,每个过滤器可以对响应进行后处理,如压缩响应数据、添加响应头信息等。

工作原理

  1. 请求阶段:客户端发送请求到服务器,服务器接收到请求后,会根据配置的过滤器链,依次将请求传递给链中的每个过滤器。每个过滤器在接收到请求后,可以对请求进行修改或增强,然后将请求传递给下一个过滤器。如果某个过滤器决定不将请求继续传递给下一个过滤器,它可以直接返回响应给客户端,从而终止请求的处理流程。
  2. 响应阶段:当请求到达目标资源并处理完成后,服务器会生成响应。响应会按照与请求阶段相反的顺序经过过滤器链,每个过滤器可以对响应进行修改或增强,最后将响应返回给客户端。

配置方式

可以通过 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 开发中&#xff0c;Filter&#xff08;过滤器&#xff09;是 Servlet 规范中的一个重要组件&#xff0c;它可以对客户端与服务器之间的请求和响应进行预处理和后处理。以下从多个方面详细介绍 Java Web 中的 Filter&#xff1a; 一、概念和作用 概念&…...

LeetCode 热题100 438. 找到字符串中所有字母异位词

LeetCode 热题100 | 438. 找到字符串中所有字母异位词 大家好&#xff0c;今天我们来解决一道经典的算法题——找到字符串中所有字母异位词。这道题在 LeetCode 上被标记为中等难度&#xff0c;要求我们在字符串 s 中找到所有是 p 的异位词的子串&#xff0c;并返回这些子串的…...

DeepSeek-R1训练时采用的GRPO算法数学原理及算法过程浅析

先来简单看下PPO和GRPO的区别&#xff1a; PPO&#xff1a;通过奖励和一个“评判者”模型&#xff08;critic 模型&#xff09;评估每个行为的“好坏”&#xff08;价值&#xff09;&#xff0c;然后小步调整策略&#xff0c;确保改进稳定。 GRPO&#xff1a;通过让模型自己生…...

Qt基于信号量QSemaphore实现的生产者消费者模型

在 Qt 中&#xff0c;信号量&#xff08;QSemaphore&#xff09;是一种用于控制对共享资源访问的同步工具。它允许一定数量的线程同时访问共享资源&#xff0c;适合用于生产者-消费者模型。 代码实现 #include <QCoreApplication> #include <QThread> #include &…...

七星棋牌 6 端 200 子游戏全开源修复版源码(乐豆 + 防沉迷 + 比赛场 + 控制)

七星棋牌源码 是一款运营级的棋牌产品&#xff0c;覆盖 湖南、湖北、山西、江苏、贵州 等 6 大省区&#xff0c;支持 安卓、iOS 双端&#xff0c;并且 全开源。这个版本是 修复优化后的二开版本&#xff0c;新增了 乐豆系统、比赛场模式、防沉迷机制、AI 智能控制 等功能&#…...

CSDN博客导出设置介绍

在CSDN编辑博客时&#xff0c;如果想导出保存到本地&#xff0c;可以选择导出为Markdown或者HTML格式。其中导出为HTML时有这几种选项&#xff1a;jekyll site&#xff0c;plain html&#xff0c;plain text&#xff0c;styled html&#xff0c;styled html with toc。分别是什…...

_ 为什么在python中可以当变量名

在 Python 中&#xff0c;_&#xff08;下划线&#xff09;是一个有效的变量名&#xff0c;这主要源于 Python 的命名规则和一些特殊的使用场景。以下是为什么 _ 可以作为变量名的原因和常见用途&#xff1a; --- ### 1. **Python 的命名规则** Python 允许使用字母&#xff…...

使用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格式说明&#xff1a; 2. 格式说明&#xff1a; chunkId&#xff1a;通常是 “RIFF” 四个字节&#xff0c;用于标识文件类型。&#xff08;wav文件格式表示&#xff09;chunkSize&#xff1a;表示整个文件除了chunkId和chunkSize这 8 个字节外的其余部分的大小。Forma…...

apload-lab打靶场

1.提示显示所以关闭js 上传<?php phpinfo(); ?>的png形式 抓包&#xff0c;将png改为php 然后放包上传成功 2.提示说检查数据类型 抓包 将数据类型改成 image/jpeg 上传成功 3.提示 可以用phtml&#xff0c;php5&#xff0c;php3 4.先上传.htaccess文件&#xff0…...

通用查询类接口数据更新的另类实现

文章目录 一、简要概述二、java工程实现1. 定义main方法2. 测试运行3. 源码放送 一、简要概述 我们在通用查询类接口开发的另类思路中&#xff0c;关于接口数据的更新&#xff0c;提出了两种方案&#xff1a; 文件监听 #mermaid-svg-oJQjD6jQ8T19XlHA {font-family:"tre…...

sentinel详细使用教学

sentinel源码地址&#xff1a; https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D sentinel官方文档&#xff1a; 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 创建项目 在控制台找个目录存放生成好的项目&#xff0c;输入命令 django-admin startproject demo_django 然后用pycharm打开项目可以…...

SuperMap iClient3D for WebGL 影像数据可视范围控制

在共享同一影像底图的服务场景中&#xff0c;如何基于用户权限体系实现差异化的数据可视范围控制&#xff1f;SuperMap iClient3D for WebGL提供了自定义区域影像裁剪的方法。让我们一起看看吧&#xff01; 一、数据制作 对于上述视频中的地图制作&#xff0c;此处不做讲述&am…...

HTML元素,标签到底指的哪块部分?单双标签何时使用?

1. 标签&#xff08;Tag&#xff09; vs 元素&#xff08;Element&#xff09; 标签&#xff08;Tag&#xff09; 标签是 HTML 中用于定义元素的符号&#xff0c;用尖括号 < > 包裹。例如 <img> 是标签。元素&#xff08;Element&#xff09; 元素是由 标签 内容…...

OpenHarmony4.1-轻量与小型系统ubuntu开发环境

因OpenHarmony官网提供包含轻量、小型与标准系统的全量代码非常宠大&#xff0c;解包后大概需要70G以上硬盘空间&#xff0c;如要编译标准系统则需要140G以上空间。 如硬盘空间有限与只使用轻量/小型OpenHarmony系统&#xff0c;则可以下载并直接使用本人裁剪源码过的ubuntu硬盘…...

秒杀系统的常用架构是什么?怎么设计?

架构 秒杀系统需要单独部署&#xff0c;如果说放在订单服务里面&#xff0c;秒杀的系统压力太大了就会影响正常的用户下单。 常用架构&#xff1a; Redis 数据倾斜问题 第一步扣减库存时 假设现在有 10 个商品需要秒杀&#xff0c;正常情况下&#xff0c;这 10 个商品应该均…...

LabVIEW中三种PSD分析VI的区别与应用

在LabVIEW的声音与振动分析工具包中&#xff0c;SVFA Power Spectral Density VI、SVFA Power Spectral Density Subset VI 和 SVFA Zoom Power Spectral Density VI 均用于信号频域分析&#xff0c;但它们在功能、适用场景和操作逻辑上存在显著差异。以下从区别、应用场合、注…...

Python 如何实现 Markdown 记账记录转 Excel 存储

文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons&#xff1a;JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram&#xff0c;自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 &#xff1f; 5 IDEA必装的插件&…...

蓝桥杯备考:动态规划入门题目之下楼梯问题

按照动态规划解题顺序&#xff0c;首先&#xff0c;我们要定义状态表示&#xff0c;这里根据题意f[i]就应该表示有i个台阶方案总数 第二步就是 确认状态转移方程&#xff0c;画图分析 所以实际上f[i] 也就是说i个台阶的方案数实际上就是第i-1个格子的方案数第i-2个格子的方案数…...

【树莓派学习】树莓派3B+的安装和环境配置

【树莓派学习】树莓派3B的安装和环境配置 文章目录 【树莓派学习】树莓派3B的安装和环境配置一、搭建Raspberry Pi树莓派运行环境1、下载树莓派镜像下载器2、配置wifi及ssh3、SSH访问树莓派1&#xff09;命令行登录2&#xff09;远程桌面登录3&#xff09;VNC登录&#xff08;推…...

算法题(83):寄包柜

审题&#xff1a; 需要我们对模拟柜子的数组进行插入数据和打印数据的操作 思路&#xff1a; 首先我们观察题目&#xff0c;发现可以用一个数组表示一个柜子&#xff0c;而数组中每个索引的位置可以看成是一个个格子。但是柜子的数据量是1e5&#xff0c;且格子的数据量是1e5.如…...

深入浅出MySQL:概述与体系结构解析

目录 1. 初识MySQL 1.1. 数据库 1.1.1. OLTP&#xff08;联机事务处理&#xff09;1.1.2. OLAP&#xff08;联机分析处理&#xff09; 2. SQL 2.1. 定义2.2. DQL&#xff08;数据查询语言&#xff09;2.3. DML&#xff08;数据操纵语言&#xff09;2.4. DDL&#xff08;数据定…...

tin这个单词怎么记

英语单词 tin&#xff0c;一般用作名词&#xff0c;意为“罐头&#xff1b;锡”&#xff1a; tin n.锡&#xff1b;罐头&#xff1b;罐&#xff1b;罐头盒&#xff1b;(盛涂料、胶水等的)马口铁罐&#xff0c;白铁桶&#xff1b;罐装物&#xff1b;金属食品盒&#xff1b;烘焙…...

【0005】Python变量详解

如果你觉得我的文章写的不错&#xff0c;请关注我哟&#xff0c;请点赞、评论&#xff0c;收藏此文章&#xff0c;谢谢&#xff01; 本文内容体系结构如下&#xff1a; 任何一个语言编写的程序或者项目&#xff0c;都需要数据的支持&#xff0c;没有数据的项目不能称之为一个…...

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 协议的发展历程&#xff1a;从 HTTP/1.0 到 HTTP/2.0 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是 Web 的基础协议&#xff0c;用于客户端和服务器之间的通信。从 HTTP/1.0 到 HTTP/2.0&#xff0c;HTTP 协议经历了多次重大改…...

PartitionFinder2 安装与使用-bioinfomatics tools 051

1. 引言 PartitionFinder2 是目前针对大中型数据集&#xff08;核苷酸、氨基酸、形态数据&#xff09;最理想的分区检测和进化模型选择工具。其推演的最优进化模型结果与 jModelTest2&#xff08;核苷酸&#xff09;和 ProTest3&#xff08;氨基酸&#xff09;的结果较为接近。…...

MCP与RAG:增强大型语言模型的两种路径

引言 近年来&#xff0c;大型语言模型&#xff08;LLM&#xff09;在自然语言处理任务中展现了令人印象深刻的能力。然而&#xff0c;这些模型的局限性&#xff0c;如知识过时、生成幻觉&#xff08;hallucination&#xff09;等问题&#xff0c;促使研究人员开发了多种增强技…...

ARM 架构下 cache 一致性问题整理

本篇文章主要整理 ARM 架构下&#xff0c;和 Cache 一致性相关的一些知识。 本文假设读者具备一定的计算机体系结构和 Cache 相关基础知识&#xff0c;适合有相关背景的读者阅读 1、引言 简单介绍一下 Cache 和内存之间的关系 在使能 Cache 的情况下&#xff0c;CPU 每次获取数…...