【获取IP归属地】Java如何实现通过IP获取IP归属地 [离线+在线](附代码,2023年亲测有效)

article/2025/10/25 6:44:12

【写在前面】
编撰这篇文章还得从之前做安全业务需求说起,我们都知道安全攻击都是在某台客户机上执行某些恶意操作(sql注入,DoS/DDoS攻击),致使服务端响应异常崩溃亦或响应数据被篡改,那么怎么去阻止这些东西呢?
首先我想到的是对访问的web端做一个IP的校验(好比阿里云服务器的安全组设置),建立一些白名单,这样能在很大程度上做到一个限制,其实在服务端也应该要开启防火墙、设置权限等。那么我们首先得知道客户端的IP是多少。接下来此文重点介绍如何获取。

文章目录

  • 1、如何获取客户端访问IP
  • 2、如何通过IP获取归属地(离线+在线)
    • 2.1 离线模式
      • 第一步:下载离线包ip2region.xdb
      • 第二步:引入离线包
      • 第三步:代码实现
    • 2.2 在线模式
  • 3、推荐方式,先离线后在线
  • 4、彩蛋

1、如何获取客户端访问IP

其实获取IP是最简单的,因为只要有请求的话,都会存放在session里面的,只要通过下面这句话就可以拿到你所需要的IP,但是如何知道别人访问你的服务器呢,这个时候就需要您自己去写一个监听事件listen;
获取IP方式如下代码即可:

HttpSession session = request.getSession(false);
if (session == null) {session = request.getSession();System.out.println("session:" + session + "创建成功");session.setAttribute("ip", request.getRemoteAddr());System.out.println("----访问的IP是:"+request.getRemoteAddr()+"----");
}

控制台输出:
在这里插入图片描述

2、如何通过IP获取归属地(离线+在线)

通过上面的方式拿到了IP地址,那么我想知道是哪些地方的人访问了我们的系统的话这就需要后台去进行查询了,这才是这篇文章的核心:

2.1 离线模式

主要是通过自己本地的离线库来实现查找的,有个弊端就是需要不断的更新。

第一步:下载离线包ip2region.xdb

首先下载一个离线的IP归属映射包ip2region.xdb,没有的可以去我的百度云盘上下载
下载地址如下:
链接:https://pan.baidu.com/s/1l_Gfhl0TVPYXvpK9QSiXyw
提取码:hdd6

第二步:引入离线包

将我们的离线包放在resources目录下,如下图所示:
在这里插入图片描述
Maven引入

打开项目中的pom.xml文件,将下面的代码复制到里面去(如果有则忽略):

<!-- ip2region  --><dependency><groupId>org.lionsoul</groupId><artifactId>ip2region</artifactId><version>2.6.5</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.9</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5</version></dependency>

开始引入时候可能会报红,需要你自己去更新一下maven库
在这里插入图片描述
没有报红表示本地引入成功。

Pom.xml引入静态打包(特别关键,不然会报错)
[Xxx/ip2region.xdb] cannot be opened because it does not exist

<resource><directory>src/main/resources</directory><includes><include>jdbc.properties</include><include>*.xml</include><include>ipdb/*.xdb</include></includes>
</resource>

主要是在构建的时候我们java会变成class文件进行编译,一些静态资源需要自己手动去加才能打到jar包里面去。

第三步:代码实现

控制台效果如下所示(国内国外的都有):
在这里插入图片描述
核心实现代码(记得要引入一些依赖包哟):

String dbPath = "/ipdb/ip2region.xdb";
try {InputStream inputStream = new ClassPathResource(dbPath).getInputStream();byte[] dbBinStr = FileCopyUtils.copyToByteArray(inputStream);// 创建一个完全基于内存的查询对象searcher = Searcher.newWithBuffer(dbBinStr);
} catch (Exception e) {System.out.printf("failed to create content cached searcher: %s\n", e);
}
//把ip2r
String address = "";
try {address = searcher.search("66.249.79.193");
} catch (Exception e) {throw new RuntimeException(e);
}
System.out.println("=== 访问者的地址为:"+address+" === ");

到这里我们就只要维护好那个离线包文件就可以,定时更新一下。

2.2 在线模式

主要通过别人或者官网提供的API接口去实现查询的功能,有个弊端就是特别依赖别人的服务器,万一别人服务器挂了就访问不了了。
具体实现效果和2.1离线模式介绍的一样
在这里插入图片描述
主要实现我封装到一个java类里面,写了一些特定的方法;
如下所示:

public static String getAddress(String ip) {try {URL realUrl = new URL("http://whois.pconline.com.cn/ipJson.jsp?ip=" + ip + "&json=true");HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();conn.setRequestMethod("GET");conn.setUseCaches(false);conn.setReadTimeout(6000);conn.setConnectTimeout(6000);conn.setInstanceFollowRedirects(false);int code = conn.getResponseCode();StringBuilder sb = new StringBuilder();String ipaddr = "";if (code == 200) {InputStream in = conn.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(in));String line;while ((line = reader.readLine()) != null) {sb.append(line);}ipaddr = ip + "=" + sb.substring(sb.indexOf("addr") + 7, sb.indexOf("regionNames") - 3);}return ipaddr;} catch (Exception e) {e.printStackTrace();return null;}
}

调用地方如下所示:

String address = IpAddressUtils.getAddress("66.249.79.193");
System.out.println("=== (在线)访问者的地址为:"+address+" === ");

3、推荐方式,先离线后在线

【重要】其实我们可以结合两个使用一起,先采用离线,如果发现为null的话则调用在线查询的方式。这样在一定的程度上能够保证数据的完整性,都有不足的话就互补一下;如下所示逻辑:

System.out.println("--- (在线+离线)访问者的IP为:66.249.79.193 --- ");//================离线模式获取=start====================//String dbPath = "/ipdb/ip2region.xdb";try {InputStream inputStream = new ClassPathResource(dbPath).getInputStream();byte[] dbBinStr = FileCopyUtils.copyToByteArray(inputStream);// 创建一个完全基于内存的查询对象searcher = Searcher.newWithBuffer(dbBinStr);} catch (Exception e) {System.out.printf("failed to create content cached searcher: %s\n", e);}//把ip2rString address = "";try {address = searcher.search("221.231.220.212");} catch (Exception e) {throw new RuntimeException(e);}
//        String address = IpAddressUtils.getCityInfo("66.249.79.193");System.out.println("=== (离线)访问者的地址为:"+address+" === ");//================离线模式获取=end====================////======================在线模式获取 start========================//if("".equals(address)){address = IpAddressUtils.getAddress("66.249.79.193");System.out.println("=== (在线)访问者的地址为:"+address+" === ");}//======================在线模式获取 end========================//

4、彩蛋

如果觉得这篇文章对您有帮助的话,想支持博主的可以上皇榜看看哟,皇榜点击此处进入


http://chatgpt.dhexx.cn/article/CCgONS2T.shtml

相关文章

1.Java获取本机IP地址,主机名,域名

1.如何在程序中获取本机的IP地址&#xff0c;主机名以及域名呢&#xff1f; 在java中&#xff0c;我们可以利用java.net.InetAddress这个类来实现。 InetAddress 类提供了操作 IP 地址的各种方法。该类本身没有构造方法&#xff0c;而是通过调用相关静态方法获取实例。 InetA…

Java通过Ip2region实现IP定位

我们在一些短视频平台上可以看到,视频作者或评论区可以显示IP地址,这其实就是根据IP获取到的我们可以通过一些在线网站就可以看到我们当前的公网IP和IP定位,最近有个需求也需要通过请求获取客户端的IP和IP的定位,于是通过一系列的百度,最终选择使用Ip2region这个工具库来进行定…

ip解析 java_JAVA解析纯真IP地址库

http://lumaqq.linuxsir.org/article/qqwry_format_detail.html&#xff0c;这里就不多叙述了。 看下JAVA代码中怎么解析IP的吧。(代码参考至lumaQQ.谢谢开源作者luma) 解析的主类 package com.showtime.IPparse; import java.io.File; import java.io.FileNotFoundException; …

Java后台获取IP地址位置信息

最近做一个项目&#xff0c;某个模块需要根据IP地址获取区域位置和运营商信息&#xff0c;以前都是根据淘宝提供的一个免费获取该信息接口 http://ip.taobao.com/service/getIpInfo.php?ip112.10.111.18 返回结果为 {"msg": "Server is busy ,Current qps 8…

java 根据ip获取地区信息

离线版本&#xff1a; 依赖&#xff1a; maven <dependency><groupId>org.lionsoul</groupId><artifactId>ip2region</artifactId><version>1.7</version> </dependency> gradle implementation org.lionsoul:ip2region:2…

Java根据IP地址获取对应归属地

1 前言 最近&#xff0c;各大平台都新增了评论区显示发言者ip归属地的功能&#xff0c;例如哔哩哔哩&#xff0c;微博&#xff0c;知乎等等&#xff0c;下面&#xff0c;就来讲讲&#xff0c;Java 中是如何获取 IP 属地的 2 获取IP地址 在Java中有多种获取IP地址的方式,就不…

L58.linux命令每日一练 -- 第九章 Linux进程管理命令 -- pgrep和kill

9.3 pgrep&#xff1a;查找匹配条件的进程 9.3.1 命令详解 ​ 【命令星级】 ★★★★☆ ​ 【功能说明】 ​ pgrep命令可以查找匹配条件的进程号。 ​ 【语法格式】 pgrep [option] [pattern] pgrep [选项] [匹配添加]​ **说明&#xff1a;**在pgrep命令及后面的选项和匹…

Linux命令之查找进程pgrep

概述 pgrep命令是通过名称从运行进程队列中查找进程&#xff0c;并且显示查找到的进程ID。 如果我们想要查找正常运行的java进程&#xff08;通常是tomcat进程&#xff09;&#xff0c;那么可以使用如下语句&#xff1a; ps -ef | grep java | grep -v grep | gawk -n {prin…

linuxpgrepgrep_Linux pgrep与kill的使用

想结束系统中指定的进程&#xff0c;有以下指令可能参考&#xff1a; ps -ef | grep pure-ftpd | grep -v grep | awk {print $2" "$3} | xargs kill -9 pkill pure-ftpd killall -9 nginx 或者 kill -9 ps aux |grep -i nginx |grep -v grep |awk {print $2} kill…

linux 命令 pgrep

linux查看服务pid pgrep是一个命令行实用程序&#xff0c;根据给定的条件查找正在运行的程序的进程id。它可以是完整的或部分的进程名、运行该进程的用户或其他属性。 语法&#xff1a; pgrep [options] pattern 当在没有任何选项的情况下调用时&#xff0c;pgrep将显示与给…

linux查看进程pgrep,查看进程PID专用工具-------pgrep

一、Linux命令pgrep简单介绍 pgrep是linux中常用的通过程序名称来查询进程的工具&#xff0c;一般是用来判断程序是否正在运行及查找正在运行进程的PID信息。通过pgrep命令&#xff0c;可以只指定进程的一部分名称从运行进程队列中进行查看进程的PID信息&#xff0c;但只输出PI…

linux shell pgrep命令使用方法(pgrep指令)获取进程号、统计进程数量(学会区分Linux进程进程名)

文章目录 问题背景pgrep指令help文档使用示例1. 列出匹配进程的PID和进程名称&#xff08;-l&#xff09;&#xff08;默认只能从进程名的子集字符串匹配&#xff0c;如果要使用完整进程名的子集字符串匹配&#xff0c;请加-f参数&#xff0c;下同&#xff09;2. 列出匹配进程的…

pgrep

Pgrep 用于根据进程的name查找进程的pid。例如&#xff1a;

Linux pgrep命令

1 pgrep pgrep是一个根据名称查找进程ID的命令&#xff0c;返回的是进程ID&#xff0c;若存在当个进程&#xff0c;则分为不同的行返回ID&#xff08;默认实现&#xff09;。 2 示例 查找java进程&#xff1a; pgrep java上图还显示了ps与pgrep的区别&#xff0c;简单来说&…

【笔记11】个人扫盲:内存与CPU中的核、线程、物理CPU、逻辑CPU

文章目录 CPU与内存CPU内存什么是通道常见问题 物理CPU和逻辑CPU常见问题LINUX查看WINDOW查看 CPU与内存 CPU CPU&#xff08;Central Processing Unit&#xff09;即中央处理器。CPU从内存&#xff08;Memory&#xff09;或缓存&#xff08;Cache&#xff09;中取出指令&…

Linux下区分物理CPU、逻辑CPU和CPU核数

一、概念 ① 物理CPU 实际Server中插槽上的CPU个数 物理cpu数量&#xff0c;可以数不重复的 physical id 有几个 ② 逻辑CPU Linux用户对 /proc/cpuinfo 这个文件肯定不陌生. 它是…

记录一个有意思的cpu逻辑cpu核数问题(已解决)

top命令查看逻辑cpu个数的时候发现只有20个 实际上服务器的的逻辑cpu个数是32个 物理cpu核数 PS&#xff1a;该问题也存在于部分新旧服务器上&#xff0c;网上没找到答案&#xff0c;特此记录。希望未来可以得到答案。 2021年09月27日更新 目前认为最近用到了多少cpu核数就显…

物理CPU,物理CPU内核,逻辑CPU概念详解

1.说明 CPU(Central Processing Unit)是中央处理单元&#xff0c; 本文介绍物理CPU&#xff0c;物理CPU内核&#xff0c;逻辑CPU&#xff0c; 以及他们三者之间的关系&#xff0c; 一个物理CPU可以有1个或者多个物理内核&#xff0c; 一个物理内核可以作为1个或者2个逻辑CPU。 …

Linux下区分物理CPU、逻辑CPU、CPU核数、线程数以及查看命令

概念 ① 物理CPU 实际服务器中插槽上的CPU个数 是指物理上&#xff0c;也就是硬件上存在着几颗物理cpu,指的是真实存在是cpu处理器的个数&#xff0c;1个代表一颗&#xff0c;2个代表2颗cpu处理器。 物理cpu数量&#xff0c;可以数不重复的 physical id 有几个 ② 逻辑CPU Lin…

linux服务器的物理CPU,CPU核数,逻辑CPU及Hadoop的Vcore

linux服务器的物理CPU&#xff0c;CPU核数&#xff0c;逻辑CPU及Hadoop的Vcore 1、Linux服务器的核数的概念 物理CPU&#xff1a; 服务器上真实存在的CPU&#xff0c;可以看到 CPU的核 (core)&#xff1a; 一个CPU上包含多少核(core)&#xff0c;真实存在但不能直接看到 总核数…