JAVA:Filer过滤器+案例:请求IP访问限制和请求返回值修改
JAVA:Filer过滤器
介绍
Java中的Filter也被称为过滤器,它是Servlet技术的一部分,用于在web服务器上拦截请求和响应,以检查或转换其内容。
Filter的urlPatterns可以过滤特定地址http的请求,也可以利用Filter对访问请求的数据IP做限制。
文档为本人学习java过滤器过程中做的学习记录。
主要用途:
- 认证过滤:检查用户请求并确定是否合法。
- 登记日志:记录请求和响应的日志。
- 改变请求和响应:可以修改请求头和响应头。
- 数据压缩:在发送大数据前,可以压缩数据。
- 加密:对请求和响应进行加密和解密。
使用说明
Spring项目中,创建类继承Filter,实现init、doFilter、destroy方法;
- init:只在项目启动的时候运行,用来做数据的初始化
- doFilter:数据过滤,每次http请求都会过滤;filterChain.doFilter(request, servletResponse)前面的程序程序是在执行目标程序前执行,后面的程序是在目标程序后执行,若doFilter程序没有执行filterChain.doFilter,请求将会被拦截。
- destroy:项目结束时运行
多个过滤器执行顺序
注意:SpringBoot项目中,多个过滤器时,@Order + @WebFilter + @ServletComponentScan 是无法实现按顺序执行过滤器的,推荐使用FilterRegistrationBean实现过滤。
- 原因详细分析见:https://blog.csdn.net/Zong_0915/article/details/126747302
案例(使用FilterRegistrationBean限制过滤器执行循序+限制IP+修改请求返回值)
案例:有两个过滤器:MyFilter01和MyFilter02,要求按先执行过滤器MyFilter01,再执行过滤器MyFilter02顺序。
MyFilter01实现对IP的白名单限制(限制127.0.0.1仅可以访问一次),以及请求返回值的更写。
MyFilter02仅用于体现执行顺序。
- 案例参考地址:
https://blog.csdn.net/zhanwuguo8346/article/details/120498756
创建过滤器:MyFilter01用于限制访问IP,修改请求返回值;
@Slf4j
public class MyFilter01 implements Filter {private Map<String, Integer> whiteIPMap;private List<String> alwaysIPList;public MyFilter01(Map<String, Integer> whiteIPMap, List<String> alwaysIPList) {this.alwaysIPList = alwaysIPList;this.whiteIPMap = whiteIPMap;}private final ObjectMapper objectMapper = new ObjectMapper();private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("/swagger-resources", "/v3/swagger-login", "/v2/api-docs")));private static Map<String, Integer> whiteIpMapDay = new HashMap<>();@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("(MyFilter01)项目开始时候执行:------->>>init");System.out.println("(MyFilter01)whiteIPMap:" + whiteIPMap);System.out.println("(MyFilter01)alwaysIPList:" + alwaysIPList);whiteIpMapDay.putAll(whiteIPMap);}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("(MyFilter01)项目每次http请求时候执行:------->>>doFilter.start");HttpServletRequest request = (HttpServletRequest) servletRequest;String ipAddr = getIpAddr(request);log.info("PermissionFilter 过滤器,请求ip为:{}", ipAddr);String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");boolean contains = ALLOWED_PATHS.contains(path);servletResponse.setCharacterEncoding("utf-8");servletResponse.setContentType("text/html;charset=utf-8");if (alwaysIPList.contains(ipAddr) && contains) {filterChain.doFilter(request, servletResponse);} else {if (whiteIpMapDay.containsKey(ipAddr)) {Integer integer = whiteIpMapDay.get(ipAddr);if (integer > 0) {if (contains) {filterChain.doFilter(request, servletResponse);} else {whiteIpMapDay.put(ipAddr, (whiteIpMapDay.get(ipAddr) - 1));filterChain.doFilter(request, servletResponse);}} else {BaseResponse<Void> baseResponse = new BaseResponse<>();baseResponse.setCode(-1);baseResponse.setMessage("请求被拒绝,本IP:" + ipAddr + "每天只允许调用:" + whiteIPMap.get(ipAddr) + "次!");String response = objectMapper.writeValueAsString(baseResponse);setServletResponseMessage(servletResponse, response);}} else {BaseResponse<Void> baseResponse = new BaseResponse<>();baseResponse.setMessage("不支持本IP请求:" + ipAddr);baseResponse.setCode(-1);String response = objectMapper.writeValueAsString(baseResponse);setServletResponseMessage(servletResponse, response);}}System.out.println("(MyFilter01)项目每次http请求时候执行:------->>>doFilter.end");}@Overridepublic void destroy() {System.out.println("(MyFilter01)项目结束时候执行:------->>>destroy");}/*** 处理返回是getWriter()还是getOutputStream();* getWriter():out对象用于处理字符流数据。* getOutputStream():os用于输出字符流数据或者二进制的字节流数据都可以。*/private void setServletResponseMessage(ServletResponse servletResponse, String response) {try {servletResponse.getWriter().write(response);} catch (IOException e) {throw new RuntimeException(e);} catch (IllegalStateException e) {servletResponse.setContentType("text/plain;charset=UTF-8"); // 设置内容类型和编码try {ServletOutputStream outputStream = servletResponse.getOutputStream();outputStream.write(response.getBytes(StandardCharsets.UTF_8)); // 写入字节数组} catch (IOException ex) {throw new RuntimeException(ex);}}}public static String getIpAddr(HttpServletRequest request) {String ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {//根据网卡取本机配置的IPInetAddress inet = null;try {inet = InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}
// ipAddress= inet.getHostAddress();ipAddress = "127.0.0.1";}}//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割if (ipAddress.length() > 15) { //"***.***.***.***".length() = 15if (ipAddress.indexOf(",") > 0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}}return ipAddress;}}
过滤器:MyFilter02仅作日志记录。体现执行顺序
public class MyFilter02 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("(MyFilter02)项目开始时候执行:------->>>init");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("(MyFilter02)项目每次http请求时候执行:------->>>doFilter.start");filterChain.doFilter(servletRequest, servletResponse);System.out.println("(MyFilter02)项目每次http请求时候执行:------->>>doFilter.end");}@Overridepublic void destroy() {System.out.println("(MyFilter02)项目结束时候执行:------->>>destroy");}}
application.yml中设置白名单访问次数,一直有权限访问的白名单。
127.0.0.1限制仅可以访问一次。
permission:white-ip: '{"127.0.0.1": 1, "192.168.16.30": 2}'always-ip: 127.0.0.1,127.0.0.1
创建配置类:FilterConfig使用@Value读取配置文件值,注册FilterRegistrationBean到Spring容器中,并设置两个过滤器的执行顺序和过滤路径
@Configuration
public class FilterConfig { @Value("#{${permission.white-ip}}")private Map<String, Integer> whiteIPMap;@Value("#{'${permission.always-ip}'.split(',')}")private List<String> alwaysIPList;@Beanpublic FilterRegistrationBean<MyFilter01> myFilterRegistrationBean01() {FilterRegistrationBean<MyFilter01> bean = new FilterRegistrationBean<>();bean.setFilter(new MyFilter01(whiteIPMap, alwaysIPList));bean.addUrlPatterns("/api/*");bean.setOrder(1);return bean;}@Beanpublic FilterRegistrationBean<MyFilter02> myFilterRegistrationBean02() {FilterRegistrationBean<MyFilter02> bean = new FilterRegistrationBean<>();bean.setFilter(new MyFilter02());bean.addUrlPatterns("/*");bean.setOrder(2);return bean;}
}
程序中用到的BaseResponse类:
@Data
public class BaseResponse<T> implements Serializable {private int code;private T data;private String message;private String description;public BaseResponse() {}public BaseResponse(int code, T data, String message, String description) {this.code = code;this.data = data;this.message = message;this.description = description;}public BaseResponse(int code, T data, String message) {this(code, data, message, "");}public BaseResponse(int code, T data) {this(code, data, "", "");}public BaseResponse(ErrorCodeEnum errorCode) {this(errorCode.getCode(), null, errorCode.getMessage(), errorCode.getDescription());}
}
测试结果:
第一次执行接口ApiPost(127.0.0.1)接口返回:数据正常创建
第二次执行接口ApiPost(127.0.0.1)接口返回:提示IP只能每天访问一次(这里没有提供更新:MyFilter01.whiteIpMapDay来实现每天可反问一次,可以使用@Schedule每天定时对静态变态做充值)。
执行日志:可以看出过滤器按照顺序执行
参考网址
https://blog.csdn.net/zhanwuguo8346/article/details/120498756
https://blog.csdn.net/Zong_0915/article/details/126747302
相关文章:
JAVA:Filer过滤器+案例:请求IP访问限制和请求返回值修改
JAVA:Filer过滤器 介绍 Java中的Filter也被称为过滤器,它是Servlet技术的一部分,用于在web服务器上拦截请求和响应,以检查或转换其内容。 Filter的urlPatterns可以过滤特定地址http的请求,也可以利用Filter对访问请求…...
FastAPI -- 第三弹(自定义响应、中间件、代理、WebSockets)
路径操作的高级配置 OpenAPI 的 operationId from fastapi import FastAPIapp FastAPI()# 通过 operation_id 参数设置 app.get("/items/", operation_id"some_specific_id_you_define") async def read_items():return [{"item_id": "F…...
网安小贴士(16)网络安全体系
前言 网络安全体系是一个综合性的系统,旨在保护网络系统中的硬件、软件和数据免受未经授权的访问、泄露、破坏或篡改。这个体系涉及多个方面,包括网络安全策略、安全技术和安全管理等。 一、网络安全体系概述 网络安全体系通常包括以下几个关键组成部分…...
UCOSIII 中断管理接口剖析
引言 在实时操作系统中,中断处理是一个非常重要的环节。理解和掌握中断处理流程对提高系统实时性和稳定性至关重要。本文将详细解析uCOS-III内核中的中断管理接口,包括 OSIntEnter() 和 OSIntExit() 函数的流程,并结合流程图对各个步骤进行说…...
windows 11 PC查询连接过的wlan密码
1:管理员打开cmd 2:输入netsh wlan show profiles 3:netsh wlan show profiles Shw2024-5G keyclear 密码关键内容:12345678...
npm install 出现canvas错误
npm install canvas2.8.0 --ignore-scripts只要是:npm ERR! Failed at the XXXX.X.X install script 这种错误 都可以:npm install XXXX.X.X --ignore-scripts进行更改 https://blog.csdn.net/YXWik/article/details/119039561...
Python爬虫入门篇学习记录
免责声明 本文的爬虫知识仅用于合法和合理的数据收集,使用者需遵守相关法律法规及目标网站的爬取规则,尊重数据隐私,合理设置访问频率,不得用于非法目的或侵犯他人权益。因使用网络爬虫产生的任何法律纠纷或损失,由使用…...
怎样对 PostgreSQL 中的慢查询进行分析和优化?
🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会!📚领书:PostgreSQL 入门到精通.pdf 文章目录 怎样对 PostgreSQL 中的慢查询进行分析和优化?一、理解慢查询的危害二、找出慢查询&#x…...
Springboot项目远程部署gitee仓库(docker+Jenkins+maven+git)
创建一个Springboot项目,勾选web将该项目创建git本地仓库,再创建远程仓库推送上去 创建TestController RestController RequestMapping("/test") public class TestController { GetMapping("/hello") public String sayHelloJe…...
Chromium CI/CD 之Jenkins实用指南2024- Windows节点开启SSH服务(七)
1.引言 在现代软件开发和持续集成的过程中,自动化部署和远程管理是不可或缺的关键环节。SSH(Secure Shell)协议以其强大的安全性和灵活性,成为连接和管理远程服务器的首选工具。对于使用Windows虚拟机作为Jenkins从节点的开发者而…...
阿里大数据面试题集锦及参考答案(3万字长文:持续更新)
目录 MapReduce Shuffle为什么要将数据写入环形缓冲区 MapReduce Shuffle为什么容易发生数据倾斜 Hadoop HA当一个Namenode挂掉,会有数据丢失吗 数据倾斜发生的位置 Combiner了解吗? 什么情况下不能用Combiner? Sum、Count、Count(distinct)哪些能用、哪些不能用Comb…...
springboot 配置 spring data redis
1、在pom.xml引入父依赖spring-boot-starter-parent,其中2.7.18是最后一版支持java8的spring <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.18</…...
Numpy基础用法
Numpy基础用法 numpy.all()num.sun() numpy.all() numpy 中的 all() 函数用于测试 NumPy 数组中所有元素是否都满足指定条件。它接受一个 NumPy 数组作为输入,并返回一个布尔值,指示数组中所有元素是否都满足条件。让我们通过具体的代码示例来深入探讨 n…...
设计模式--享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享大量细粒度的对象来减少内存消耗。这个模式的核心思想是把对象的状态分为内在状态和外在状态,其中内在状态是可以共享的,而外在状态是需要独立维护的。 享…...
可视化剪辑,账号矩阵,视频分发,聚合私信一体化营销工具 源----代码开发部署方案
可视化剪辑: 为了实现可视化剪辑功能,可以使用流行的视频编辑软件或者开发自己的视频编辑工具。其中,通过设计用户友好的界面,用户可以简单地拖拽和放大缩小视频片段,剪辑出满足需求的视频。在开发过程中,可…...
CCF-CSP认证考试 202406-2 矩阵重塑(其二) 100分题解
更多 CSP 认证考试题目题解可以前往:CSP-CCF 认证考试真题题解 原题链接: 202406-2 矩阵重塑(其二) 时间限制: 1.0 秒 空间限制: 512 MiB 题目背景 矩阵转置操作是将矩阵的行和列交换的过程。在转置过程…...
初阶数据结构的实现1 顺序表和链表
顺序表和链表 1.线性表1.1顺序表1.1.1静态顺序表(不去实现)1.1.2动态顺序表1.1.2.1 定义程序目标1.1.2.2 设计程序1.1.2.3编写代码1.1.2.3测试和调试代码 1.1.2 顺序表的问题与思考 1.2链表1.2.1链表的概念及结构1.2.1.1 定义程序目标1.2.1.2 设计程序1.…...
破解反爬虫策略 /_guard/auto.js(一) 原理
背景 当用代码或者postman访问一个网站的时候,访问他的任何地址都会返回<script src"/_guard/auto.js"></script>,但是从浏览器中访问显示的页面是正常的,这种就是网站做了反爬虫策略。本文就是带大家来破解这种策略&…...
40.简易频率计(基于等精度测量法)(3)
(1)BCD8421码:十进制数字转换成BCD8421码的方法 补零:你需要显示多少位数字,就在前面补上四倍的位宽。比如你要显示一个十进制8位的数字,就在前面补上8*432个零。判断:判断补零部分显示的十进制…...
关于Centos停更yum无法使用的解决方案
最近在使用Centos7.9系统时候,发现yum仓库无法进行安装软件包了,官方说2024年6月30日进行停更,停更后无法提供对应的软件服务。 我在使用yum安装包的时候发现确实不能使用官方服务了: CentOS停更的影响 CentOS停止更新之后&#…...
插画感言:成都亚恒丰创教育科技有限公司
插画感言:笔触间的灵魂对话 在这个快节奏、高压力的时代,我们时常在寻找那些能够触动心灵、让灵魂得以片刻栖息的角落。而插画,这一融合了艺术与情感的独特形式,便如同一股清泉,缓缓流淌进每个人的心田,以…...
【算法】数组中的第K个最大元素
难度:中等 题目: 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题…...
Perl 语言的特点
Perl 语言入门学习可以涵盖多个方面,包括其特点、基本语法、高级特性以及学习资源和社区支持等。以下是一个详细的入门学习指南: 一、Perl 语言的特点 文本处理能力强:Perl 提供了丰富的字符串处理函数和正则表达式的支持,非常适…...
NLP教程:1 词袋模型和TFIDF模型
文章目录 词袋模型TF-IDF模型词汇表模型 词袋模型 文本特征提取有两个非常重要的模型: 词集模型:单词构成的集合,集合自然每个元素都只有一个,也即词集中的每个单词都只有一个。 词袋模型:在词集的基础上如果一个单词…...
【开源 Mac 工具推荐之 2】洛雪音乐(lx-music-desktop):免费良心的音乐平台
旧版文章:【macOS免费软件推荐】第6期:洛雪音乐 Note:本文在旧版文章的基础上,新更新展示了一些洛雪音乐的新功能,并且描述更为详细。 简介 洛雪音乐(GitHub 名:lx-music-desktop )…...
AMEYA360:思瑞浦推出汽车级理想二极管ORing控制器TPS65R01Q
聚焦高性能模拟芯片和嵌入式处理器的半导体供应商思瑞浦3PEAK(股票代码:688536)发布汽车级理想二极管ORing控制器TPS65R01Q。 TPS65R01Q拥有20mV正向调节功能,降低系统损耗。快速反向关断(Typ:0.39μs),在电池反向和各种汽车电气瞬…...
简约的悬浮动态特效404单页源HTML码
源码介绍 简约的悬浮动态特效404单页源HTML码,页面简约美观,可以做网站错误页或者丢失页面,将下面的代码放到空白的HTML里面,然后上传到服务器里面,设置好重定向即可 效果预览 完整源码 <!DOCTYPE html> <html><head><meta charset="utf-8&q…...
Golang 创建 Excel 文件
经常会遇到需要导出数据报表的需求,除了可以通过 encoding/csv 导出 CSV 以外,还可以使用 https://github.com/qax-os/excelize 导出 xlsx 等格式的 excel,下面封装了一个方法,支持多 sheet 的 excel 数据生成,导出按需…...
探索GitHub上的两个革命性开源项目
在数字世界中,总有一些项目能够以其创新性和实用性脱颖而出,吸引全球开发者的目光。今天,我们将深入探索GitHub上的两个令人惊叹的开源项目:Comic Translate和GPTPDF,它们不仅改变了我们处理信息的方式,还极…...
SpringBoot框架学习笔记(三):Lombok 和 Spring Initailizr
1 Lombok 1.1 Lombok 介绍 (1)Lombok 作用 简化JavaBean开发,可以使用Lombok的注解让代码更加简洁Java项目中,很多没有技术含量又必须存在的代码:POJO的getter/setter/toString;异常处理;I/O…...
php网站建设流程/学seo如何入门
前段时间的帖子,利用TPYBoard v102做的DIY照相机,周末实物终于做出来了,加了两个按键模块和一个5110,做的有点糙啊----望大家勿怪,哈哈哈。拍出来图片还算清晰,串口摄像头模块用的30w像素的(贫穷…...
广告素材网站哪个比较好/深圳网络推广哪家公司好
1.今天使用 _itoa函数,出现蛋疼的问题原来又是微软的一套。 2.如何解决呢? 在第一行添一句:#define _CRT_SECURE_NO_WARNINGS //关闭安全检查 代码如下: 1 #define _CRT_SECURE_NO_WARNINGS2 # include<stdio.h>3 # …...
手贱wordpress5.0/站长工具seo综合查询是什么
【导读】:前面的文章介绍了移动平均滤波器、IIR滤波器、梳状滤波器,今天来谈谈FIR滤波器的设计实现。 本篇文章依然采用4W1H进行描述,从What Why Where When How几个维度展开。为了便于理解4W1H,依然把5W1H的图附上。 FIR滤波器之What? LTI线性时不变系统冲激响应按照…...
好视频下载软件/网站推广优化公司
函数调用中的意义不明确的参数(Naked parameters )可能会影响可读性,当参数名称的含义不明显时,请为参数添加 C 样式注释 (/* ... */) Bad // func printInfo(name string, isLocal, done bool)printInfo("foo", true…...
网页游戏网站排名前10名/软文代写公司
VirtIO 是一个用来实现“虚拟IO”的通用框架,典型的用于虚拟机上面实现虚拟的pci,网卡,磁盘等虚拟设备,kvm等都使用了这个技术。大概浏览了一下相关的内核代码,这个virtio应该是专门应用于那种“半虚拟化?&…...
网站的主题是什么/sem优化是什么
之前在写代码的时候,如果需要让线程等待一会,就直接使用sleep()方法,一直也没有出过问题。而wait()方法的出场率很高,每次打一个句点的时候,对象的方法弹出来,总是能看到wait()在其中,wait()是一…...