JavaWeb 学习笔记 7:Filter
JavaWeb 学习笔记 7:Filter
1.快速开始
使用过滤器的方式与 Servlet 类似,要实现一个Filter接口:
@WebFilter("/*")
public class FirstFilter implements Filter {public void init(FilterConfig filterConfig) throws ServletException {}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("pre chain.doFilter");// 放行请求chain.doFilter(request, response);System.out.println("after chain.doFilter");}public void destroy() {}
}
这里 @WebFilter 指定的是过滤器拦截的路径规则,/*是对所有请求进行拦截。
Fitler接口有三个方法:
init,过滤器初始化时执行doFilter,拦截请求destroy,过滤器销毁时执行
在doFilter方法中,通常需要执行chain.doFilter()方法放行请求,否则请求就不会正常被 Servlet 进行处理,直接被 Filter 阻断。
添加一个 JSP 以观察 Filter 的执行过程:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<h1>Hello World!</h1>
<% System.out.println("hello.jsp..."); %>
</body>
</html>
请求这个 JSP 会看到如下输出:
pre chain.doFilter
hello.jsp...
after chain.doFilter
整个过程可以用下图表示:

2.Filter 拦截路径
Filter 可以拦截以下几种路径:
- 具体路径,比如
/jsp/hello.jsp,只有访问这个 JSP 的请求会被拦截。 - 目录,比如
/jsp/*,访问/jsp这个目录下的所有资源路径都会被拦截。 - 后缀名拦截,比如
*.jsp,左右访问后缀名为.jsp的资源都会被拦截。 - 拦截全部,
/*,访问任意资源都会被拦截。
3.过滤器链
一个 Web 应用可以配置多个过滤器,这些过滤器合称“过滤器链”。
下面看实际演示。
在应用中设置两个过滤器:
@WebFilter("/*")
public class Filter1 implements Filter {public void init(FilterConfig filterConfig) throws ServletException {}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("before filter1 chain.doFilter");chain.doFilter(request, response);System.out.println("after filter1 chain.doFilter");}public void destroy() {}
}@WebFilter("/*")
public class Filter2 implements Filter {public void init(FilterConfig filterConfig) throws ServletException {}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("before filter2 chain.doFilter");chain.doFilter(request, response);System.out.println("after filter2 chain.doFilter");}public void destroy() {}
}
请求 JSP 页面可以看到如下输出:
before filter1 chain.doFilter
before filter2 chain.doFilter
hello.jsp...
after filter2 chain.doFilter
after filter1 chain.doFilter
如果使用注解配置过滤器,过滤器在过滤器链上的先后顺序由过滤器类名做字典排序决定。
4.案例:登录验证
使用过滤器可以对一些需要在多个 Servlet 中进行的统一处理进行简化。比如每个 Servlet 都需要的请求内容乱码处理或者响应报文添加统一的报文头等等。
这里展示如何使用过滤器实现登录验证功能。
@WebFilter("/*")
public class LoginFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 对登录相关请求和静态资源进行放行String[] paths = new String[]{"/user/login","/user/registry","/user/check_code","/css/","/imgs/","/index.jsp"};if (!(request instanceof HttpServletRequest &&response instanceof HttpServletResponse)){throw new RuntimeException("This is not web Application.");}HttpServletRequest hRequest = (HttpServletRequest) request;HttpServletResponse hResponse = (HttpServletResponse) response;String url = hRequest.getRequestURL().toString();String prefix = "http://"+hRequest.getHeader("host")+hRequest.getContextPath();for (String path: paths){if (url.indexOf(prefix+path) == 0){// 符合规则,放行System.out.println("放行"+url);chain.doFilter(hRequest, hResponse);return;}}// 检查是否登录,如果没有登录,重定向到登录页面Object username = hRequest.getSession().getAttribute("username");if (username == null){hResponse.sendRedirect("/login-demo/user/login");return;}// 已经登录,放行chain.doFilter(hRequest, hResponse);}@Overridepublic void destroy() {}
}
需要注意的是,这里除了需要通过 Session 判断是否登录状态,没有登录的让重定向到登录页面以外,还需要对于特殊路径进行放行,否则有些页面就无法正常显示。在我们这个示例中,需要非登录状态就可以访问的资源有:
- CSS
- 图片
- 登录相关的 Servlet
- 注册相关的 Servlet
- 返回验证码的 Servlet
- 首页(用于重定向到登录页)
对于这些特殊资源,这里简单地用字符串匹配的方式判断和处理。
5.Listener
Listener、Filter 和 Servlet 是 JavaWeb 的三大组件。
Listener 的用途是监听 Application\Session\Request 三个对象的创建、销毁或属性的修改和删除。
具体包含以下监听器:

利用 ServletContext监听器,我们可以在 Servlet 容器创建后执行一些应用的初始化代码:
@WebListener
public class ApplicationRunner implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {// 这里执行一些应用的初始化工作System.out.println("Web Application is already run...");}@Overridepublic void contextDestroyed(ServletContextEvent sce) {// 这里执行应用退出时的清理工作}
}
使用监听器很容易,只要实现相应的接口,并使用@WebListener注解标记类即可。
本文的完整示例可以从这里获取。
6.参考资料
- 黑马程序员JavaWeb基础教程
相关文章:
JavaWeb 学习笔记 7:Filter
JavaWeb 学习笔记 7:Filter 1.快速开始 使用过滤器的方式与 Servlet 类似,要实现一个Filter接口: WebFilter("/*") public class FirstFilter implements Filter {public void init(FilterConfig filterConfig) throws ServletE…...
【AI视野·今日Robot 机器人论文速览 第三十五期】Mon, 18 Sep 2023
AI视野今日CS.Robotics 机器人学论文速览 Mon, 18 Sep 2023 Totally 44 papers 👉上期速览✈更多精彩请移步主页 Interesting: 📚GelSplitter, 基于近红外与可见光融合实现高精度surfaceNormal重建的触觉传感器。(from 华中科技大学) 基于分光镜的紧凑型…...
Elasticsearch 在bool查询中使用分词器
1. 创建索引 test setting和mappings 设置了自定义分词映射规则。 PUT /test {"settings": {"analysis": {"filter": {"my_synonym": {"type": "synonym","updateable": true,"synonyms_path&qu…...
在Python中创建相关系数矩阵的6种方法
相关系数矩阵(Correlation matrix)是数据分析的基本工具。它们让我们了解不同的变量是如何相互关联的。在Python中,有很多个方法可以计算相关系数矩阵,今天我们来对这些方法进行一个总结 Pandas Pandas的DataFrame对象可以使用c…...
物联网、工业大数据平台 TDengine 与苍穹地理信息平台完成兼容互认证
当前,在政府、军事、城市规划、自然资源管理等领域,企业对地理信息的需求迅速增加,人们需要更有效地管理和分析地理数据,以进行决策和规划。在此背景下,“GIS 基础平台”应运而生,它通常指的是一个地理信息…...
this.$nextTick()的使用场景
事件循环机制: 同步代码执行->查找异步队列,推入执行栈,执行Vue.nextTick[事件循环1]->查找异步队列,推入执行栈,执行Vue.nextTick[事件循环2]->查找异步队列,推入执行栈,执行Vue.nex…...
idea(第一次)启动项目,端口变成了8080
先上配置 server:port: 9569 spring:profiles:active: dev 该排查的问题也都没问题,重启idea也试过了,还是8080 解决办法:点击右侧的maven ,左上角的重新导入 reimport all maven projects 我又没有改动pom文件,居然还要点这…...
brpc 学习(一)M1 MacOS构建方法
tags: brpc categories: brpc 写在前面 实习阶段初次接触到 RPC 这样一种协议, 以及 brpc 这样一个很棒的框架, 但是当时没时间认真深入学习, 就是围绕使用 demo 开发, 还是有点不知其所以然的, 最近抽空来学习一下 brpc, 首要的一点就是在开发机上构建项目, 并且能够跑起来,…...
Python 与 Qt c++ 程序共享内存,传递图片
python 代码 这里Python 使用 shared_memory QT 使用 QSharedMemory 简单协议: 前面4个字节是 图片with,height,0,0 后面是图片数据 import sys import struct def is_little_endian():x0x12345678y struct.pack(I,x)return y[0]0x78print(f"is_little_end…...
【2023年中国研究生数学建模竞赛华为杯】E题 出血性脑卒中临床智能诊疗建模 问题分析、数学模型及代码实现
【2023年中国研究生数学建模竞赛华为杯】E题 出血性脑卒中临床智能诊疗建模 1 题目 1.1 背景介绍 出血性脑卒中指非外伤性脑实质内血管破裂引起的脑出血,占全部脑卒中发病率的10-15%。其病因复杂,通常因脑动脉瘤破裂、脑动脉异常等因素,导致…...
2024字节跳动校招面试真题汇总及其解答(五)
17.TCP的拥塞控制 TCP 的拥塞控制是指在 TCP 连接中,发送端和接收端通过协作来控制网络中数据包的流量,避免网络拥塞。TCP 的拥塞控制是 TCP 协议的重要组成部分,它可以确保 TCP 连接的稳定性和可靠性。 TCP 的拥塞控制主要有以下几个目的: 防止网络拥塞:当网络中的数据…...
如何撤销某个已经git add的文件以及如何撤销所有git add提交的文件?
如果你想撤销已经添加(git add)到暂存区的单个文件,可以使用 git reset 命令。以下是具体的命令格式: git reset <file>在这里,<file> 是你想要从暂存区中移除的文件名。比如,如果你想要撤销已…...
JVM高级性能调试
标准的JVM是配置为了高吞吐量,吞吐量是为了科学计算和后台运行使用,而互联网商业应用,更多是为追求更短的响应时间,更低的延迟Latency(说白了就是更快速度),当用户打开网页没有快速响应…...
APK的反编译,签名,对齐
APK的反编译,签名,对齐 – WhiteNights Site 2023年9月22日 标签:Android, 应用开发 记录下相关的命令行参数。 APK的打包与解包 java -jar apktool.jar 首先,需要一个jar包,以我在用的为例:apktool_2.8.…...
Django(20):信号机制
目录 信号的工作机制信号的应用场景两个简单例子Django常用内置信号如何放置信号监听函数代码自定义信号第一步:自定义信号第二步:触发信号第三步:将监听函数与信号相关联 信号的工作机制 Django 框架包含了一个信号机制,它允许若…...
31.链表练习题(2)(王道2023数据结构2.3.7节16-25题)
【前面使用的所有链表的定义在第29节】 试题16:两个整数序列A,B存在两个单链表中,设计算法判断B是否是A的连续子序列。 bool Pattern(LinkList L1,LinkList L2){ //此函数实现比较L1的子串中是否有L2LNode *p, *q; //工作在L1,p记录L1子串…...
排序算法之归并排序
一、归并排序的形象理解 原题链接 示例代码 void merge_sort(int q[], int l, int r) {if (l > r) return;int mid l r >> 1;merge_sort(q, l, mid), merge_sort(q, mid 1, r);int k 0, i l, j mid 1;while (i < mid && j < r) //第一处if (q[i]…...
macOS 下 Termius 中文显示为乱码
👨🏻💻 热爱摄影的程序员 👨🏻🎨 喜欢编码的设计师 🧕🏻 擅长设计的剪辑师 🧑🏻🏫 一位高冷无情的编码爱好者 大家好,我是 DevO…...
Apifox接口测试工具详细解析
最近发现一款接口测试工具--apifox,我我们很难将它描述为一款接口管理工具 或 接口自测试工具。 官方给了一个简单的公式,更能说明apifox可以做什么。 Apifox Postman Swagger Mock JMeter Apifox的特点: 接口文档定义: Api…...
Python 实现 PDF 文件转换为图片 / PaddleOCR
文章用于学习记录 文章目录 前言一、PDF 文件转换为图片二、OCR 图片文字识别提取三、服务器端下载运行 PaddleOCR四、下载权重文件总结 前言 文字识别(Optical Character Recognition,简称OCR)是指将图片、扫描件或PDF、OFD文档中的打印字符…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
归并排序:分治思想的高效排序
目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...
Java中栈的多种实现类详解
Java中栈的多种实现类详解:Stack、LinkedList与ArrayDeque全方位对比 前言一、Stack类——Java最早的栈实现1.1 Stack类简介1.2 常用方法1.3 优缺点分析 二、LinkedList类——灵活的双端链表2.1 LinkedList类简介2.2 常用方法2.3 优缺点分析 三、ArrayDeque类——高…...
更新 Docker 容器中的某一个文件
🔄 如何更新 Docker 容器中的某一个文件 以下是几种在 Docker 中更新单个文件的常用方法,适用于不同场景。 ✅ 方法一:使用 docker cp 拷贝文件到容器中(最简单) 🧰 命令格式: docker cp <…...
Python打卡训练营学习记录Day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
开源 vGPU 方案:HAMi,实现细粒度 GPU 切分
本文主要分享一个开源的 GPU 虚拟化方案:HAMi,包括如何安装、配置以及使用。 相比于上一篇分享的 TimeSlicing 方案,HAMi 除了 GPU 共享之外还可以实现 GPU core、memory 得限制,保证共享同一 GPU 的各个 Pod 都能拿到足够的资源。…...
