获取请求IP以及IP解析成省份
某些业务需要获取请求IP以及将IP解析成省份之类的,于是我写了一个工具类,可以直接COPY
/*** IP工具类* @author xxl* @since 2023/11/9*/
@Slf4j
public class IPUtils {/*** 过滤本地地址*/public static final String LOCAL_ADDRESS = "127.0.0.1";public static final String LOOP_BACK_ADDRESS = "0:0:0:0:0:0:0:1";/*** 离线查询IP地址的数据文件,这个文件去ip2region GitHub官方仓库获取*/private static String IP_ADDRESS_FILE_PATH ;/*** 前从 xdb 文件中加载出来 VectorIndex 数据,然后全局缓存,* 每次创建 Searcher 对象的时候使用全局的 VectorIndex 缓存可以减少一次固定的 IO 操作,* 从而加速查询,减少 IO 压力。*/private static byte[] vIndex= null;private static Searcher searcher = null;static {try {//这个ip2region.xdb我是放在/resources/data/ip2region.xdb目录下的String fileName = "/data/ip2region.xdb";File existFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);if(!FileUtil.exist(existFile)) {InputStream resourceAsStream = IPUtils.class.getResourceAsStream(fileName);FileUtil.writeFromStream(resourceAsStream, existFile);}IP_ADDRESS_FILE_PATH = existFile.getPath();// 从 db 中预先加载 VectorIndex 缓存,并且把这个得到的数据作为全局变量,后续反复使用。vIndex = Searcher.loadVectorIndexFromFile(IP_ADDRESS_FILE_PATH);// 使用全局的 vIndex 创建带 VectorIndex 缓存的查询对象。searcher = Searcher.newWithVectorIndex(IP_ADDRESS_FILE_PATH, vIndex);} catch (Exception e) {throw new RuntimeException("IPUtils class load error", e);}}/*** 每个线程需要单独创建一个独立的 Searcher 对象,但是都共享全局的制度 vIndex 缓存。* @param ip IP* @return IP地址*/public static String getCity(String ip) {String search = null;try {search = searcher.search(ip);} catch (Exception e) {throw new RuntimeException("getCity fail",e);}return search;}/*** 获取 IP** @param request 请求* @return 字符串*/public static String getIp(HttpServletRequest request) {String ip = null;try {//解析IPip = new ChainUtils<>(request.getHeader("X-Forwarded-For"))//多次反向代理后会有多个ip值,第一个ip才是真实ip.chain(re -> StrUtil.isNotBlank(re) ? (re.contains(DOT) ? re.substring(0, re.indexOf(DOT)) : EMPTY) : re)//依次查找IP.chain(re -> StrUtil.isNotBlank(re) ? re : request.getHeader("X-Real-IP")).chain(re -> StrUtil.isNotBlank(re) ? re : request.getHeader("Proxy-Client-IP")).chain(re -> StrUtil.isNotBlank(re) ? re : request.getHeader("WL-Proxy-Client-IP")).chain(re -> StrUtil.isNotBlank(re) ? re : request.getHeader("HTTP_CLIENT_IP")).chain(re -> StrUtil.isNotBlank(re) ? re : request.getHeader("HTTP_X_FORWARDED_FOR")).chain(re -> StrUtil.isNotBlank(re) ? re : request.getRemoteAddr())//过滤本地地址.chain(re -> StrUtil.isNotBlank(re) ? (LOOP_BACK_ADDRESS.equals(re) ? LOCAL_ADDRESS : re) : re).getValue(true);} catch (Exception e) {log.error("getIp fail", e);}return ip;}
}
使用以上工具类需要以下依赖和一个自定义工具类
<!-- 解析IP -->
<dependency><groupId>org.lionsoul</groupId><artifactId>ip2region</artifactId><version>2.7.0</version>
</dependency>
<!-- hutool -->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.20</version>
</dependency>
ChainUtil:为什么写这个工具类在解析请求中的IP参考了https://blog.csdn.net/chwshuang/article/details/71940858
此博客中部分代码如下图可以发现有很多if判断,很难看不好维护。于是就写了以下的工具类
/*** @author: xxl* @since: 2023/11/9* @description: 解决if,else地狱*/
@AllArgsConstructor
public class ChainUtil<T> {/*** 存储的值*/private T value;public <E> ChainUtil<E> chain(Function<T,E> function) {return new ChainUtil<>(function.apply(value));}/*** 获取存储的值** @param isNullForException 如果存储的值为null是否抛出异常* @return T*/public T getValue(boolean isNullForException) {if (isNullForException) {Assert.notNull(value, () -> new RuntimeException("chain value is null"));}return value;}
}
if地狱
相关文章:

获取请求IP以及IP解析成省份
某些业务需要获取请求IP以及将IP解析成省份之类的,于是我写了一个工具类,可以直接COPY /*** IP工具类* author xxl* since 2023/11/9*/ Slf4j public class IPUtils {/*** 过滤本地地址*/public static final String LOCAL_ADDRESS "127.0.0.1&quo…...

YOLOv8-seg改进:复现HIC-YOLOv5,HIC-YOLOv8-seg助力小目标分割
🚀🚀🚀本文改进:HIC-YOLOv8-seg:1)添加一个针对小物体的额外预测头,以提供更高分辨率的特征图2)在backbone和neck之间采用involution block来增加特征图的通道信息;3)在主干网末端加入 CBAM 的注意力机制; 🚀🚀🚀HIC-YOLOv8-seg小目标分割检测&复杂场景…...

vscode 终端进程启动失败: shell 可执行文件“C:\Windows\System32\WindowsPower
vscode 终端进程启动失败: shell 可执行文件“C:\Windows\System32\WindowsPower 第一次用vscode,然后遇到这个问题,在设置里搜索 terminal.integrated.defaultProfile.windows 将这里的null改成"Command Prompt" 重启就可以了...

【中间件篇-Redis缓存数据库02】Redis高级特性和应用(慢查询、Pipeline、事务、Lua)
Redis高级特性和应用(慢查询、Pipeline、事务、Lua) Redis的慢查询 许多存储系统(例如 MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作。所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阀值,就将这条命令的相关…...

栈 和 队列
什么是栈? 一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出(LIFO - Last In First Out)的原则。 从数据结构的角度来看&…...

【推荐】一款AI写作大师、问答、绘画工具-「智元兔 AI」
在当今技术飞速发展的时代,越来越多的领域开始应用人工智能(Artificial Intelligence,简称AI)。其中,AI写作工具备受瞩目,备受推崇。在众多的选择中,智元兔AI是一款在笔者使用过程中非常有帮助的…...

阿里云付费用户破100万 用户规模亚洲最大
导读阿里巴巴集团公布2018财年第一季度财报,阿里云达到一个重要里程碑,云计算付费用户数量首次超过100万,成为亚洲首家达到百万级用户规模的云计算公司。同时,企业级市场被云计算人工智能等新技术全面激活,推动该季度营…...

人工智能基础——Python:Matplotlib与绘图设计
人工智能的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心,我为大家整理了一份600多G的学习资源,基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…...
Ubuntu 配置 Github 的 SSH keys
先进入已有的 Git 目录或使用新建的一个 Git 仓库下。 设置 Github 用户名和邮箱: $ git config --global user.name [Github用户名] $ git config --global user.email [Github认证邮箱]生成 SSH 密钥文件: $ ssh-keygen -t rsa -C [Github认证邮箱]…...
Flink—— Flink Data transformation(转换)
Flink数据算子转换有很多类型,各位看官看好,接下来,演示其中的十八种类型。 1.Map(映射转换) DataStream → DataStream 将函数作用在集合中的每一个元素上,并返回作用后的结果,其中输入是一个数据流&…...
前端读取文件当文件选择相同文件名的文件,内容不会变化
前端读取文件当文件选择相同文件名的文件,内容不会变化 今天遇到个奇怪的bug,使用打开文件,并选择文件时,正常情况会读取文件信息。 但是如果先选择相同的文件名,则内容不会发生变化。 先说结论 只要不使用事件中e…...

PHP 服装销售管理系统mysql数据库web结构layUI布局apache计算机软件工程网页wamp
一、源码特点 PHP 服装销售管理系统是一套完善的web设计系统mysql数据库 ,对理解php编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 php服装销售管理系统1 二、功能介绍 (1)员工管理:对员工信息…...

用于图像处理的高斯滤波器 (LoG) 拉普拉斯
一、说明 欢迎来到拉普拉斯和高斯滤波器的拉普拉斯的故事。LoG是先进行高斯处理,继而进行拉普拉斯算子的图像处理算法。用拉普拉斯具有过零功能,实现边缘岭脊提取。 二、LoG算法简述 在这篇博客中,让我们看看拉普拉斯滤波器和高斯滤波器的拉普…...

【h5 uniapp】 滚动 滚动条,数据跟着变化
uniapp项目 需求: 向下滑动时,数据增加,上方的日历标题日期也跟着变化 向上滑动时,上方的日历标题日期跟着变化 实现思路: 初次加载目前月份的数据 以及下个月的数据 this.getdate()触底加载 下个月份的数据 onReach…...

ModStartBlog v8.5.0 评论开关布局调整,系统后台全面优化
ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用,支持后台一键快速安装,让开发者能快的实现业务功能开发。 系统完全开源,基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场,后台一键快速安装 …...

django|报错SQLite 3.8.3 or later is required的解决方案
迁移原同事写的程序,到新服务器上边。运行报错。解决方案有三种 降低django版本升级sqlite3,不低于3.8.3版本修改django源码 方案一、降低django版本 卸载高版本django pip uninstall django安装低版本,如 pip install django2.1.7注意&…...

通达OA get_datas.php前台sql注入-可获取数据库session登入后台漏洞复现 [附POC]
文章目录 通达OA get_datas.php前台sql注入-可获取数据库session登入后台漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 通达OA get_datas.php前台sql注入-可获取数据库session登入后台漏洞复现…...

苹果官方:所有国行iPhone 15系列都在中国生产!
近几年来,国内供应链逐渐外迁,而拥有庞大劳动力市场的印度却成为了香饽饽,逐渐获得越来越多企业的重视,就连苹果公司也将其视为发展的重要战略要地。 自从苹果扩大印度生产iPhone规模后,很快流言四起,各种负…...

Oracle 安装及 Spring 使用 Oracle
参考内容: docker安装oracle数据库史上最全步骤(带图文) Mac下oracle数据库客户端 Docker安装Oracle docker能安装oracle吗 Batch script for add a auto-increased primary key for exist table with records Docker 安装 Oracle11g 注意&a…...
element-ui 表格 点击选中
element-ui 表格 点击选中 复制element ui 表格 <template><el-table:data"tableData"style"width: 100%"><el-table-columnprop"date"label"日期"width"180"></el-table-column><el-table-col…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...