获取请求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 {
            //解析IP
            ip = 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地狱

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/123465.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VUE获取当前日期的周日和周六

<template><div><div @click="handleLast()">上一周</div><div @click="handleNext()">下一周</div><el-calendarref="monChild"v-model="value":first-day-of-week="7":range=&q…

React进阶之路(二)-- 组件通信、组件进阶

文章目录 组件通信组件通信的意义父传子实现props说明子传父实现兄弟组件通信跨组件通信Context通信案例 React组件进阶children属性props校验组件生命周期 组件通信 组件通信的意义 组件是独立且封闭的单元&#xff0c;默认情况下组件只能使用自己的数据&#xff08;state&a…

2022年接口测试总结【温故知新系列】

本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什么要做&#xff1f; 第二部分&#xff1…

Spring Gateway基础知识总结

本文主要总结Spring Gateway的基础用法&#xff0c;内容包括网关、Spring Gateway工作流程、Spring Cloud Gateway搭建、路由配置方式、负载均衡实现、断言工厂这几个部分 目录 1. 网关 1.1 网关介绍 1.2 网关对比 1.3 Spring Gateway 1.4 核心概念 1.6 总结 2. Spring …

什么GAN生成对抗网络?生成对抗网络可以干什么?

生成对抗网络(Generative Adversarial Nets,简称GAN)。神经网络分很多种,有普通的前向传播网络,有分析图片的CNN卷积神经网络,有分析系列化数据比如语言、文字的RNN循环神经网络,这些神经网络都是用来输入数据,得到想要的结果,我们看中的是这些神经网络中很好地将数据与…

SpringCloud——消息总线——Bus

1.什么是总线&#xff1f; 我们在微服务的项目中&#xff0c;通常会构建一个共同的消息主题&#xff0c;然后需要的服务可以连接上来&#xff0c;该主题中产生的消息会被监听和消费&#xff0c;这种我们称为消息总线。 SpringCloud Bus 配合SpringCloud Config使用可以实现配置…

RestTemplate配置和使用

在项目中&#xff0c;如果要调用第三方的http服务&#xff0c;就需要发起http请求&#xff0c;常用的请求方式&#xff1a;第一种&#xff0c;使用java原生发起http请求&#xff0c;这种方式不需要引入第三方库&#xff0c;但是连接不可复用&#xff0c;如果要实现连接复用&…

基础课26——业务流程分析方法论

基础课25中我们提到业务流程分析方法包括以下几种&#xff1a; 价值链分析法&#xff1a;主要是找出或设计出哪些业务能够使得客户满意&#xff0c;实现客户价值最大化的业务流程。要进行价值链分析的时候可以从企业具体的活动进行细分&#xff0c;细分的具体方面可以从生产指…

运行springboot时提示:源值 7 已过时,将在未来版本中删除,并且提示java.time not exist, LocaDateTime类找不到。

运行springboot时提示&#xff1a;源值 7 已过时&#xff0c;将在未来版本中删除&#xff0c;并且提示 java.time not exist, LocaDateTime类找不到。 解决方法&#xff1a; 方式一&#xff1a;通过IDEA修改这几个地方的JDK版本 1&#xff09;打开ProjectStructure->Proj…

多篇论文介绍-Wiou

论文地址 目录 https://arxiv.org/pdf/2301.10051.pdf 01 CIEFRNet&#xff1a;面向高速公路的抛洒物检测算法 02改进 YOLOv5 的 PDC 钻头复合片缺损识别 03 基于SimAM注意力机制的DCN-YOLOv5水下目标检测 04 基于改进YOLOv7-tiny 算法的输电线路螺栓缺销检测 05 基于改…

机器学习中的假设检验

正态性检验相关分析回归分析 所谓假设检验&#xff0c;其实就是根据原假设来构造一种已知分布的统计量来计算概率&#xff0c;根据概率值大小来判断能否拒绝原假设&#xff0c;从而得到一种结论。假设检验的过程就是&#xff0c;构造一个原假设成立条件下的事件A&#xff0c;计…

基于斑马算法的无人机航迹规划-附代码

基于斑马算法的无人机航迹规划 文章目录 基于斑马算法的无人机航迹规划1.斑马搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用斑马算法来优化无人机航迹规划。 1.斑马搜索算法 …

内网可达网段探测netspy- Mac环境

netspy是一款快速探测内网可达网段工具 当我们进入内网后想要扩大战果&#xff0c;那我们可能首先想知道当前主机能通哪些内网段。 netspy正是一款应用而生的小工具&#xff0c;体积较小&#xff0c;速度极快&#xff0c;支持跨平台&#xff0c;支持多种协议探测&#xff0c;…

软件测试/校招推荐丨鼎捷软件股份有限公司岗位开放

点此获取更多相关资料 软件测试工程师 岗位职责 负责公司产品的日常测试工作&#xff1b;依据软件需求和非功能需求&#xff0c;编写测试方案和测试用例&#xff0c;设计测试脚本&#xff1b;负责服务器系统和软件的日常维护工作&#xff0c;为上线部署和运维活动提供技术支持…

HarmonyOS应用开发

引言 本章将深入探讨 HarmonyOS 应用开发的关键方面&#xff0c;包括应用的生命周期、数据存储和网络访问。了解这些内容对于创建功能丰富、高效的 HarmonyOS 应用至关重要。 目录 HarmonyOS 应用的生命周期HarmonyOS 应用的数据存储HarmonyOS 应用的网络访问总结 1. Harmo…

python 时间加法 输出t分钟后的时间

题目&#xff1a; 现在时间是a点b分&#xff0c;请问t分钟后&#xff0c;是几点几分&#xff1f; 输入&#xff1a; 第一行包含一个整数a 第二行包含一个整数b 第三行包含一个整数t 其中&#xff0c;0≤a≤23&#xff0c;0≤b≤59&#xff0c;0≤t&#xff0c;t分钟后还…

【Linux】进程的基本概念和进程控制

TOC 目录 一.冯诺依曼体系结构 二. 操作系统(Operator System) 概念 设计OS的目的 定位 总结 系统调用和库函数概念 进程 基本概念 描述进程-PCB task_struct-PCB的一种 task_ struct内容分类 组织进程 查看进程 通过系统调用获取进程标识符 进程状态 D--深度…

Android内存回收机制、GC算法及内存问题分析解决

Android内存回收机制、GC算法及内存问题分析解决 在Android开发中&#xff0c;Java内存回收和垃圾收集&#xff08;GC&#xff09;机制是确保应用程序高效运行的关键部分。针对不同对象存活率&#xff0c;Android平台采用了引用计数算法和可达性分析法来判定对象的可回收性&am…

【代码随想录】算法训练营 第二十天 第六章 二叉树 Part 6

654. 最大二叉树 题目 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回…

IntelliJ IDEA 2023.2.1 (Ultimate Edition) 版本 Git 如何合并多次的本地提交进行 Push

本心、输入输出、结果 文章目录 IntelliJ IDEA 2023.2.1 (Ultimate Edition) 版本 Git 如何合并多次的本地提交进行 Push前言为什么需要把多次本地提交合并合并提交的 2 种形式:事中合并、事后合并事中合并事后合并:支持拆分为多组提交弘扬爱国精神IntelliJ IDEA 2023.2.1 (U…