基于Spring MVC的客户端真实IP获取方案解析
文章目录
- 基于Spring MVC的客户端真实IP获取方案解析
- 概述
- 核心方法解析
- 代码实现
- 工作流程
- IP获取优先级策略
- IP有效性验证
- 异常处理与日志
- 使用场景
- 注意事项
- 扩展建议
基于Spring MVC的客户端真实IP获取方案解析
概述
在Web应用开发中,准确获取客户端真实IP地址是常见的需求。本文介绍一个基于Spring MVC实现的客户端IP获取方案ClientIpController,该方案支持多种代理场景下的IP识别,并包含完善的校验机制。
核心方法解析
代码实现
/*** 获取客户端公网IP** @author xdr630*/
@RestController
public class ClientIpController {private static final Logger LOGGER = LoggerFactory.getLogger(KocaClientIpController.class);@GetMapping("/getRemoteIp")@ResponseBodypublic String getClientIp(HttpServletRequest request) {String clientIp = null;try {String xForwardedFor = request.getHeader("X-Forwarded-For");if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {// X-Forwarded-For:Squid 服务代理,X-Forwarded-For 可能包含多个 IP,取第一个非空的 IPclientIp = xForwardedFor.split(",")[0].trim();}if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {// Proxy-Client-IP:apache 服务代理clientIp = request.getHeader("Proxy-Client-IP");}if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {// WL-Proxy-Client-IP:weblogic 服务代理clientIp = request.getHeader("WL-Proxy-Client-IP");}if ((clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp))) {// X-Real-IP:nginx服务代理clientIp = request.getHeader("X-Real-IP");}if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {clientIp = request.getRemoteAddr();}if (clientIp != null && !clientIp.isEmpty()) {clientIp = clientIp.split(",")[0];}if (!isValidIPv4(clientIp)) {LOGGER.warn("无效的客户端 IP: {}", clientIp);// 在浏览器端显示返回nullclientIp = "null";}} catch (Exception e) {LOGGER.error("获取客户端公网IP失败", e);throw new RuntimeException(e);}return clientIp;}private boolean isValidIPv4(String ip) {String ipv4Regex = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";return Pattern.compile(ipv4Regex).matcher(ip).matches();}
}
工作流程
-
多级代理支持:依次检查以下请求头
X-Forwarded-For:处理Squid等代理的逗号分隔IPProxy-Client-IP:Apache代理WL-Proxy-Client-IP:WebLogic代理X-Real-IP:Nginx代理
-
最终回退机制
clientIp = request.getRemoteAddr();
- 结果处理
- 取首个有效IP段
- IPv4格式校验
- 异常IP返回"null"字符串
IP获取优先级策略
| 优先级 | Header名称 | 代理类型 |
|---|---|---|
| 1 | X-Forwarded-For | 通用代理/Squid |
| 2 | Proxy-Client-IP | Apache |
| 3 | WL-Proxy-Client-IP | WebLogic |
| 4 | X-Real-IP | Nginx |
| 5 | getRemoteAddr() | 直接连接 |
IP有效性验证
采用正则表达式校验IPv4格式:
^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
异常处理与日志
- WARN级别日志:记录无效IP格式
- ERROR级别日志:捕获处理异常
- 异常转换:将检查异常转为RuntimeException
使用场景
- 反向代理架构下的真实IP获取
- 客户端地理位置服务
- 访问频率控制
- 安全审计日志
注意事项
- 代理链中的首个IP可能不可信(需结合安全策略)
- 不支持IPv6地址(需扩展正则校验)
- 生产环境建议添加速率限制
- 重要场景建议结合XFF白名单验证
扩展建议
- 增加IPv6支持
- 添加可信代理IP列表验证
- 集成缓存机制防止滥用
- 补充单元测试覆盖边界情况
该方案提供了可靠的客户端IP获取实现,开发人员应根据实际网络架构调整header的检查顺序,并在安全敏感场景中补充额外的验证逻辑。
相关文章:
基于Spring MVC的客户端真实IP获取方案解析
文章目录 基于Spring MVC的客户端真实IP获取方案解析概述核心方法解析代码实现工作流程 IP获取优先级策略IP有效性验证异常处理与日志使用场景注意事项扩展建议 基于Spring MVC的客户端真实IP获取方案解析 概述 在Web应用开发中,准确获取客户端真实IP地址是常见的…...
【Web部署问题】在Tomcat中部署web项目出现http状态-404 -未找到详细解决方案
部署完tomcat记得在选中要运行的工件。 如果没有工件,或者工件有缺失东西,去这里配置工件,...
Linux——Shell编程之正则表达式与文本处理器(笔记)
目录 基础正则表达式 1:基础正则表达式示例 (4)查找任意一个字符“.”与重新字符“*” (5)查找连续字符范围“{ }” 文本处理器 一、sed工具 二、awk工具 (1)按行输出文本 (2࿰…...
Linux 进程控制(自用)
非阻塞调用waitpid 这样父进程就不会阻塞,此时循环使用我们可以让父进程执行其他任务而不是阻塞等待 进程程序替换 进程PCB加载到内存中的代码和数据 替换就是完全替换当前进程的代码段、数据段、堆和栈,保存当前的PCB 代码指的是二进制代码不是源码&a…...
05-DevOps-Jenkins自动拉取构建代码
新建Gitlab仓库 先在Gitab上创建一个代码仓库,选择创建空白项目 安装说明进行填写,然后点击创建项目 创建好的仓库是空的,什么都没有 新建一个springboot项目,用于代码上传使用。 只是为了测试代码上传功能,所以代码…...
【Spring学习】
Spring学习 简介 Spring 是一个开源的 Java 企业级开发框架,最核心的特点是: IOC(控制反转)AOP(面向切面编程) 它有完整的生态: 🚀 Spring Boot:用于快速构建服务&a…...
网络基础与 HTTP 协议
一、网络基础 (一)TCP/IP 协议族 TCP/IP 协议族是互联网通信的核心协议,它包含了多个层次的协议,共同协作实现网络通信。 1. IP 协议 IP(Internet Protocol)协议位于网络层,主要负责将数据包…...
SRS transcode支持 h264_nvenc 硬件解码方案
文章目录 SRS transcode支持 h264_nvenc 硬件解码方案1、修改文件2、重新编译3、使用 SRS transcode支持 h264_nvenc 硬件解码方案 SRS 是开源的流媒体服务,但在使用 GPU 服务器时,想要通过硬件加速,目前官方是不支持的,所以简单…...
阿里云服务器搭建开源版禅道
一,下载地址:禅道11.5版本发布,主要完善细节,修复bug,新增动态过滤机制 - 禅道下载 - 禅道项目管理软件 下载地址二: 禅道21.6.stable 实现旧编辑器撰写的文档无感升级至新版编辑器 - 禅道下载 - 禅道项目…...
【刷题Day21】TCP(浅)
说说 TCP 的四次挥手? TCP的四次挥手事用于安全关闭一个已建立的连接的过程,它确保双方都能完成数据传输并安全地释放连接资源。 简述步骤: 第一次挥手(FIN --> ACK):客户端主动关闭连接,…...
怎么用面向对象和状态机架构,设计一个通用的按键检测功能?
说起按键检测,在座的各位,哪个没被它折磨过? 我刚入门时,为了实现一个简单的按键功能,硬生生写了几十行代码,各种 if...else 嵌套,逻辑绕得我自己都头晕。 更可气的是,辛辛苦苦写完…...
Java基础系列-LinkedList源码解析
文章目录 简介LinkedList 插入和删除元素的时间复杂度?LinkedList 为什么不能实现 RandomAccess 接口? LinkedList 源码分析Node 定义初始化获取元素插入元素删除元素遍历链表 简介 LinkedList 是一个基于双向链表实现的集合类,经常被拿来和…...
day47—双指针-平方数之和(LeetCode-633)
题目描述 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a^2 b^2 c 。 示例 1: 输入:c 5 输出:true 解释:1 * 1 2 * 2 5示例 2: 输入:c 3 输出:f…...
qwen 14B模型配置文件,层名称weight_map. 28GB
qwen 14B模型配置文件,层名称weight_map. 28GB 目录 qwen 14B模型配置文件,层名称weight_map. 28GBmetadata(元数据)weight_map(权重映射)lm_head.weightmodel.layersmlp.{proj_type}.weightpost_attention_layernormself_attn.{proj_type}.{bias_or_weight}model.norm.w…...
LVDS系列8:Xilinx 7系可编程输入延迟(一)
在解析LVDS信号时,十分重要的一环就是LVDS输入信号线在经过PCB输入到FPGA中后,本来该严格对齐的信号线会出现时延,所以需要在FPGA内部对其进行延时对齐后再进行解析。 Xilinx 7系器件中用于输入信号延时的组件为IDELAYE2可编程原语࿰…...
【Oracle专栏】函数中SQL拼接参数 报错处理
Oracle相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 1.背景 最近同事反馈了一个很奇怪的问题,即有一个函数,入参是当前年月,主要作用是通过SQL语句将不合规的数据插入到指定表中,插入数据时带上入参的年月参数。当前问题:单独测试SQL没有问题可以执行成功,…...
自然语言处理(NLP)领域大图
以下是一份自然语言处理(NLP)与大模型领域的领域大图,涵盖技术框架、发展脉络、交叉融合点和应用场景的完整解析: 1. 核心技术体系 基础分析层级 词法分析:分词、词性标注、命名实体识别句法分析:依存句法…...
【Linux我做主】GDB调试工具完全指南
Linux下GDB调试工具完全指南:25个核心命令详解与实战示例 github地址 有梦想的电信狗 前言 GDB(GNU Debugger)是Linux开发中不可或缺的调试工具,尤其在定位代码逻辑错误和内存问题时表现卓越。本文基于实际开发经验࿰…...
Pycharm 如何删除某个 Python Interpreter
在PyCharm中,点击右下角的“Interpreter Settings”按钮,或者通过菜单栏选择“File” > “Settings”(macOS用户选择“PyCharm” > “Preferences”)。在设置窗口中,导航到“Project: [Your Project Name]” >…...
在 Debian 12 中恢复被删除的 smb.conf 配置文件
https://forum.ubuntu.com.cn/viewtopic.php?t494763 本文结合ai输出,内容中可能有些错误,但确实解决了我的问题,我采取保留完整输出的方式摘录。 在 Debian 12 中恢复被删除的 smb.conf 配置文件,需结合 dpkg 和 ucf(…...
Day3:个人中心页面布局前端项目uniapp壁纸实战
接下来我们来弄一下个人中心页面布局user.vue <template><view class"userLayout"><view class"userInfo"><view class"avatar"><image src"../../static/Kx.jpg" mode"aspectFill"></im…...
访问”和“初始化本质区别以及C++静态成员变量定义位置详解
💡 1.访问”和“初始化本质区别: ✅ 访问 protectedNum:Derived 作为 Base 的子类,是可以在自己的函数中访问 protectedNum 的。❌ 初始化 protectedNum:只能通过 Base 的构造函数来初始化,因为它是 Base …...
正则表达式反向引用的综合应用魔法:从重复文本到简洁表达的蜕变
“我....我要....学学学学....编程 java!” —— 这类“重复唠叨”的文本是否让你在清洗数据时头疼不已? 本文将带你一步步掌握正则表达式中的反向引用技术,并结合 Java 实现一个中文文本去重与清洗的实用工具。 结合经典的结巴实例。如何高效地将这样的…...
C实现md5功能
md5在线验证: 在线MD5计算_ip33.com 代码如下: #include "md5.h" #include <string.h> #include "stdio.h"/** 32-bit integer manipulation macros (little endian)*/ #ifndef GET_ULONG_LE #define GET_ULONG_LE(n,b,i) …...
FFmpeg+Nginx+VLC打造M3U8直播
一、视频直播的技术原理和架构方案 直播模型一般包括三个模块:主播方、服务器端和播放端 主播放创造视频,加美颜、水印、特效、采集后推送给直播服务器 播放端: 直播服务器端:收集主播端的视频推流,将其放大后推送给…...
在 Debian 10.x 安装和配置 Samba
1. 更新系统 sudo apt update sudo apt upgrade -y2. 安装 Samba sudo apt install samba -y3. 配置 Samba 备份默认配置文件 sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak编辑配置文件 sudo nano /etc/samba/smb.conf示例配置(共享目录) …...
基础(测试用例:介绍,测试用例格式,案例)
目录 测试用例介绍 测试用例编写格式 案例 测试用例介绍 用例:用户使用软件的案例场景 测试用例:是为测试项目而设计的测试执行文档 测试用例的作用: 防止漏测是实施测试的标准可以作为测试工作量的评估 测试用例编写格式 用例编号 用例…...
C++学习:六个月从基础到就业——内存管理:RAII原则
C学习:六个月从基础到就业——内存管理:RAII原则 本文是我C学习之旅系列的第十九篇技术文章,也是第二阶段"C进阶特性"的第四篇,主要介绍C中的RAII原则及其在资源管理中的应用。查看完整系列目录了解更多内容。 引言 在…...
Windows串口通信
Windows串口通信相比较Android串口通信,在开发上面相对方便一些。原理都是一样,需要仔细阅读厂商设备的串口通信协议。结合串口调试助手进行测试,测试通过后,编写代码实现。 比如近期就接触到了一款天平,其最大测量值为100g,测量精度0.001g。 拿到手之后我就先阅读串口通…...
bert项目解析
数据预处理 读取csv数据集 def read_file(file_path):data []label []with open(file_path, "r", encoding"utf-8") as file:reader csv.reader(file)next(reader) # 跳过标题行# row每一行用英文逗号分割成列表[标签,文本] 所以标签和文本用英文逗…...
