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

【 <一> 炼丹初探:JavaWeb 的起源与基础】之 Servlet 过滤器:实现请求的预处理与后处理

<前文回顾>

点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=12907601&sharerefer=PC&sharesource=FoyoDesigner&sharefrom=from_link

<今日更新>

一、过滤器:Servlet 的“门神”

在 JavaWeb 开发里,Servlet 过滤器[1] 就像个“门神”,专门在请求进门前“查岗”,在响应出门前“把关”。它能对请求和响应进行“预处理”和“后处理”,比如权限验证、日志记录、字符编码啥的。过滤器虽然“低调”,但它的作用可不容小觑。

1. 过滤器的“三板斧”

过滤器的主要功能可以概括为“三板斧”:

  1. 预处理请求:在请求到达 Servlet 之前,对请求进行一些“加工”,比如设置字符编码、验证权限啥的。
  2. 拦截请求:根据条件决定是否放行请求,比如权限不足时直接返回错误页面。
  3. 后处理响应:在响应返回给客户端之前,对响应进行一些“修饰”,比如压缩内容、添加响应头啥的。

Java Code

public class MyFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)

        throws IOException, ServletException {

        // 预处理请求

        req.setCharacterEncoding("UTF-8");

        

        // 拦截请求

        if (checkPermission(req)) {

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

        } else {

            ((HttpServletResponse) resp).sendError(HttpServletResponse.SC_FORBIDDEN, "权限不足");

        }

        

        // 后处理响应

        resp.setContentType("text/html;charset=UTF-8");

    }

    

    private boolean checkPermission(ServletRequest req) {

        // 权限验证逻辑

        return true;

    }

}

2. 过滤器的“生命周期”

过滤器的生命周期和 Servlet 差不多,主要分三步:initdoFilterdestroy

  • init:过滤器初始化时调用,通常用来加载配置、初始化资源啥的。
  • doFilter:每次请求时调用,是过滤器的核心方法。
  • destroy:过滤器销毁时调用,通常用来释放资源啥的。

Java Code

public void init(FilterConfig config) throws ServletException {

    // 初始化代码

}

public void destroy() {

    // 清理代码

}

二、过滤器的“实际应用场景”

过滤器虽然“低调”,但它的应用场景可不少。比如权限验证、日志记录、字符编码啥的,都能用过滤器来实现。

1. 权限验证

权限验证是过滤器的“拿手好戏”。比如,用户访问某个页面时,过滤器可以“查岗”,看看用户有没有权限,没权限就直接“拦下”。

Java Code

public class AuthFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)

        throws IOException, ServletException {

        HttpServletRequest httpReq = (HttpServletRequest) req;

        HttpSession session = httpReq.getSession();

        if (session.getAttribute("user") == null) {

            ((HttpServletResponse) resp).sendRedirect("login.jsp");

        } else {

            chain.doFilter(req, resp);

        }

    }

}

2. 日志记录

日志记录是过滤器的“家常便饭”。比如,每次请求时,过滤器可以“记一笔”,把请求的 URL、参数啥的都记录下来。

Java Code

public class LogFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)

        throws IOException, ServletException {

        HttpServletRequest httpReq = (HttpServletRequest) req;

        System.out.println("请求 URL: " + httpReq.getRequestURL());

        System.out.println("请求参数: " + httpReq.getQueryString());

        chain.doFilter(req, resp);

    }

}

3. 字符编码

字符编码是过滤器的“基本功”。比如,每次请求时,过滤器可以“统一”设置字符编码,避免乱码问题。

Java Code

public class EncodingFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)

        throws IOException, ServletException {

        req.setCharacterEncoding("UTF-8");

        resp.setContentType("text/html;charset=UTF-8");

        chain.doFilter(req, resp);

    }

}

三、过滤器的“历史”:从 Servlet 2.3 到 Servlet 4.0

过滤器从 Servlet 2.3 开始就有了,虽然现在 Servlet 4.0 已经“普及”了,但过滤器的“核心功能”依然没变。

1. Servlet 2.3:初代“门神”

Servlet 2.3 在 2001 年发布,过滤器是它的“初代门神”。虽然功能简单,但已经能满足大部分开发需求了。

2. Servlet 3.0:引入注解

Servlet 3.0 在 2009 年发布,引入了注解[2],让开发者能用注解配置过滤器,不用再写 web.xml 了。注解的引入,让过滤器的“玩法”更加方便。

Java Code

@WebFilter("/admin/*")

public class AuthFilter implements Filter {

    // 过滤器代码

}

3. Servlet 4.0:支持 HTTP/2

Servlet 4.0 在 2017 年发布,支持 HTTP/2[3],让 Web 应用的性能更上一层楼。HTTP/2 的引入,让过滤器的“玩法”更加高效。

四、过滤器的“骚操作”

1. 请求压缩

过滤器不仅能“查岗”,还能“修饰”响应。比如,用过滤器压缩响应内容,减少传输数据量。

Java Code

public class CompressionFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)

        throws IOException, ServletException {

        HttpServletResponse httpResp = (HttpServletResponse) resp;

        httpResp.setHeader("Content-Encoding", "gzip");

        chain.doFilter(req, new GZIPResponseWrapper(httpResp));

    }

}

2. 响应缓存

过滤器不仅能“修饰”响应,还能“缓存”响应。比如,用过滤器缓存响应内容,减少服务器压力。

Java Code

public class CacheFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)

        throws IOException, ServletException {

        HttpServletResponse httpResp = (HttpServletResponse) resp;

        httpResp.setHeader("Cache-Control", "max-age=3600");

        chain.doFilter(req, resp);

    }

}

3. 跨域处理

过滤器不仅能“缓存”响应,还能“处理”跨域。比如,用过滤器添加跨域响应头,支持跨域请求。

Java Code

public class CorsFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)

        throws IOException, ServletException {

        HttpServletResponse httpResp = (HttpServletResponse) resp;

        httpResp.setHeader("Access-Control-Allow-Origin", "*");

        httpResp.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");

        chain.doFilter(req, resp);

    }

}

专有名词解释

  1. Servlet 过滤器:一种用于在请求到达 Servlet 之前或响应返回客户端之前进行处理的组件。
  2. 注解:Annotation,一种用于配置过滤器的元数据。
  3. HTTP/2:HTTP 协议的第二个主要版本,支持多路复用、头部压缩等特性。

相关文章:

【 <一> 炼丹初探:JavaWeb 的起源与基础】之 Servlet 过滤器:实现请求的预处理与后处理

<前文回顾> 点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、过滤器&…...

DeepSeek与浏览器自动化AI Agent构建指南

文章使用到的模型可以用硅基流动中的&#xff1a; 注册链接&#xff1a;硅基流动统一登录 邀请码&#xff1a;FytHp9Xa 一、技术选型阶段 1. 基础组件选择 AI模型&#xff1a;DeepSeek-R1开放API&#xff08;对话/推理&#xff09;或DeepSeek-Coder&#xff08;代码生成&#…...

面试中常问的mysql数据库指令【杭州多测师_王sir】

数据库中的修改表结构、增删改查、用户权限操作DDL 》数据库定义语言 create database&#xff0c;create table drop tableDML 》数据库操作语言 insert into&#xff0c;delete from&#xff0c;update set&#xff0c;DQL 》数据库查询语言 select .... from....crea…...

深度学习驱动的智能化革命:从技术突破到行业实践

第一章 深度学习的技术演进与核心架构 1.1 从浅层网络到深度学习的范式转变 深度学习的核心在于通过多层次非线性变换自动提取数据特征,其发展历程可划分为三个阶段:符号主义时代的规则驱动(1950s-1980s)、连接主义时代的浅层网络(1990s-2000s)以及深度学习时代的端到端…...

基于编译器特性浅析C++程序性能优化

最近在恶补计算机基础知识&#xff0c;学到CSAPP第五章的内容&#xff0c;在这里总结并且展开一下C程序性能优化相关的内容。 衡量程序性能的方式 一般而言&#xff0c;程序的性能可以用CPE&#xff08;Cycles Per Element&#xff09;来衡量&#xff0c;其指的是处理每个元素…...

服务器上通过ollama部署deepseek

2025年1月下旬&#xff0c;DeepSeek的R1模型发布后的一周内就火了&#xff0c;性能比肩OpenAI的o1模型&#xff0c;且训练成本仅为560万美元&#xff0c;成本远低于openAI&#xff0c;使得英伟达股票大跌。 下面我们来看下如何个人如何部署deepseek-r1模型。 我是用的仙宫云的…...

Android Coil总结

文章目录 Android Coil总结概述添加依赖用法基本用法占位图变形自定义ImageLoader取消加载协程支持缓存清除缓存监听 简单封装 Android Coil总结 概述 Coil 是一个用于 Android 的 Kotlin 图像加载库&#xff0c;旨在简化图像加载和显示的过程。它基于 Kotlin 协程&#xff0…...

《安富莱嵌入式周报》第351期:DIY半导体制造,工业设备抗干扰提升方法,NASA软件开发规范,小型LCD在线UI编辑器,开源USB PD电源,开源锂电池管理

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; https://www.bilibili.com/video/BV16C95YEEZs 《安富莱嵌入式周报》第351期&#xff1a;DIY半导体…...

Redis在人员管理系统中的应用示例

用户会话管理 场景&#xff1a;用户登录后存储会话信息&#xff0c;支持多服务器共享 实现&#xff1a; 用户登录成功后&#xff0c;生成唯一Token&#xff08;如JWT&#xff09;&#xff0c;作为Redis的Key Value存储用户ID、角色、权限等信息&#xff0c;设置过期时间&…...

The Wedding Juicer POJ - 2227

采取从外层边界&#xff0c;一步一步向内部拓展的策略&#xff0c;具体来说&#xff0c;一开始将最外面一层的点加入队列&#xff0c;并标记这些点的坐标已经被访问 取出队列中高度最低的点&#xff0c;将其弹出&#xff0c;查看其上下左右的点&#xff0c;如果新点没有被访问…...

# 深入理解RNN(一):循环神经网络的核心计算机制

深入理解RNN&#xff1a;循环神经网络的核心计算机制 RNN示意图 引言 在自然语言处理、时间序列预测、语音识别等涉及序列数据的领域&#xff0c;循环神经网络(RNN)一直扮演着核心角色。尽管近年来Transformer等架构逐渐成为主流&#xff0c;RNN的基本原理和思想依然对于理…...

分布式锁—6.Redisson的同步器组件

大纲 1.Redisson的分布式锁简单总结 2.Redisson的Semaphore简介 3.Redisson的Semaphore源码剖析 4.Redisson的CountDownLatch简介 5.Redisson的CountDownLatch源码剖析 1.Redisson的分布式锁简单总结 (1)可重入锁RedissonLock (2)公平锁RedissonFairLock (3)联锁MultiL…...

同步 Fork 仓库的命令

同步 Fork 仓库的命令 要将您 fork 的仓库的 main 分支与原始仓库&#xff08;fork 源&#xff09;同步&#xff0c;您可以使用以下命令&#xff1a; 首先&#xff0c;确保您已经添加了原始仓库作为远程仓库&#xff08;如果尚未添加&#xff09;&#xff1a; git remote add…...

基于PySide6的CATIA零件自动化着色工具开发实践

引言 在汽车及航空制造领域&#xff0c;CATIA作为核心的CAD设计软件&#xff0c;其二次开发能力对提升设计效率具有重要意义。本文介绍一种基于Python的CATIA零件着色工具开发方案&#xff0c;通过PySide6实现GUI交互&#xff0c;结合COM接口操作实现零件着色自动化。该方案成…...

OpenManus 的提示词

OpenManus 的提示词 引言英文提示词的详细内容工具集的详细说明中文翻译的详细内容GitHub 仓库信息背景分析总结 引言 OpenManus 是一个全能 AI 助手&#xff0c;旨在通过多种工具高效地完成用户提出的各种任务&#xff0c;包括编程、信息检索、文件处理和网页浏览等。其系统提…...

Ubuntu-docker安装mysql

只记录执行步骤。 1 手动下载myql镜像&#xff08;拉去华为云镜像&#xff09; docker pull swr.cn-east-3.myhuaweicloud.com/library/mysql:latest配置并启动mysql 在opt下创建文件夹 命令&#xff1a;cd /opt/ 命令&#xff1a;mkdir mysql_docker 命令&#xff1a;cd m…...

Electron桌面应用开发:自定义菜单

完成初始应用的创建Electron桌面应用开发&#xff1a;创建应用&#xff0c;随后我们就可以自定义软件的菜单了。菜单可以帮助用户快速找到和执行命令&#xff0c;而不需要记住复杂的快捷键&#xff0c;通过将相关功能组织在一起&#xff0c;用户可以更容易地发现和使用应用程序…...

理解 JavaScript 中的浅拷贝与深拷贝

在 JavaScript 开发中&#xff0c;我们经常需要复制对象或数组。然而&#xff0c;复制的方式不同&#xff0c;可能会导致不同的结果。本文将详细介绍 浅拷贝 和 深拷贝 的概念、区别以及实现方式&#xff0c;帮助你更好地理解和使用它们。 1. 什么是浅拷贝&#xff1f; 定义 …...

【Java开发指南 | 第三十五篇】Maven + Tomcat Web应用程序搭建

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 前言Maven Tomcat Web应用程序搭建1、使用Maven构建新项目2、单击项目&#xff0c;连续按两次shift键&#xff0c;输入"添加"&#xff0c;选择"添加框架支持"3、选择Java Web程序4、点击&…...

从0到1入门Linux

一、常用命令 ls 列出目录内容 cd切换目录mkdir创建新目录rm删除文件或目录cp复制文件或目录mv移动或重命名文件和目录cat查看文件内容grep在文件中查找指定字符串ps查看当前进程状态top查看内存kill终止进程df -h查看磁盘空间存储情况iotop -o直接查看比较高的磁盘读写程序up…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...