CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

Java中是如何获取IP属地的?-源码交易平台丞旭猿

细心的小伙伴可能会发现,抖音新上线了 IP 属地的功能,小伙伴在发表动态、发表评论以及聊天的时候,都会显示自己的 IP 属地信息。

下面,我就来讲讲,Java 中是如何获取 IP 属地的,主要分为以下几步:

  • 通过 HttpServletRequest 对象,获取用户的 IP 地址
  • 通过 IP 地址,获取对应的省份、城市

首先需要写一个 IP 获取的工具类,因为每一次用户的 Request 请求,都会携带上请求的 IP 地址放到请求头中。

publicclassIpUtil{publicstaticStringgetIpAddr(ServerHttpRequestrequest){HttpHeadersheaders=request.getHeaders();StringipAddress=headers.getFirst("X-Forwarded-For");if(ipAddress==null||ipAddress.length()==0||"unknown".equalsIgnoreCase(ipAddress)){ipAddress=headers.getFirst("Proxy-Client-IP");}if(ipAddress==null||ipAddress.length()==0||"unknown".equalsIgnoreCase(ipAddress)){ipAddress=headers.getFirst("WL-Proxy-Client-IP");}if(ipAddress==null||ipAddress.length()==0||"unknown".equalsIgnoreCase(ipAddress)){ipAddress=request.getRemoteAddress().getAddress().getHostAddress();if(ipAddress.equals("127.0.0.1")||ipAddress.equals("0:0:0:0:0:0:0:1")){// 根据网卡取本机配置的IPtry{InetAddressinet=InetAddress.getLocalHost();ipAddress=inet.getHostAddress();}catch(UnknownHostExceptione){log.error("根据网卡获取本机配置的IP异常",e);}}}// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照,分割if(ipAddress!=null&&ipAddress.indexOf(",")>0){ipAddress=ipAddress.split(",")[0];}returnipAddress;}}

这里有三个名词,分别是

  • X-Forwarded-For:一个 HTTP 扩展头部,主要是为了让 Web 服务器获取访问用户的真实 IP 地址。每个 IP 地址,每个值通过逗号+空格分开,最左边是最原始客户端的 IP 地址,中间如果有多层代理,每⼀层代理会将连接它的客户端 IP 追加在 X-Forwarded-For 右边。
  • X-Real-IP:一般只记录真实发出请求的客户端IP
  • Proxy-Client-IP:这个一般是经过 Apache http 服务器的请求才会有,用 Apache http 做代理时一般会加上 Proxy-Client-IP 请求头
  • WL-Proxy-Client-IP:也是通过 Apache http 服务器,在 weblogic 插件加上的头。

在我们获取到用户的 IP 地址后,那么就可以获取对应的 ip 信息了。

插播一条广告:需要开通正版IDEA的可以联系我,56元一年,正版授权,官网可查有效期,有需要的加我 微 信:poxiaozhiai6,备注:903。

我在 Github 冲浪的时候,发现了 Ip2region 项目。

一个准确率 99.9% 的离线 IP 地址定位库,0.0x 毫秒级查询,ip2region.db 数据库只有数 MB,提供了 java,php,c,python,nodejs,golang,c 等查询绑定和Binary,B树,内存三种查询算法。

数据聚合了一些知名 ip 到地名查询提供商的数据,这些是他们官方的的准确率,经测试着实比经典的纯真 IP 定位准确一些。ip2region 的数据聚合自以下服务商的开放 API 或者数据。

备注:如果上述开放API或者数据都不给开放数据时ip2region将停止数据的更新服务。

每条 ip 数据段都固定了格式:

_城市Id|国家|区域|省份|城市|ISP_

只有中国的数据精确到了城市,其他国家有部分数据只能定位到国家,后前的选项全部是 0,已经包含了全部你能查到的大大小小的国家

生成的数据库文件 ip2region.db 只有几 MB,最小的版本只有 1.5MB,随着数据的详细度增加数据库的大小也慢慢增大,目前还没超过 8MB。

内置的三种查询算法

全部的查询客户端单次查询都在 0.x 毫秒级别,内置了三种查询算法

  • memory 算法:整个数据库全部载入内存,单次查询都在0.1x毫秒内,C语言的客户端单次查询在0.00x毫秒级别。
  • binary 算法:基于二分查找,基于ip2region.db文件,不需要载入内存,单次查询在0.x毫秒级别。
  • b-tree 算法:基于btree算法,基于ip2region.db文件,不需要载入内存,单词查询在0.x毫秒级别,比binary算法更快。

ip2region安装

下面,就让我们给项目引入 ip2region,进行 ip 信息转换吧

首先引入 maven 依赖

<dependency><groupId>org.lionsoulgroupId><artifactId>ip2regionartifactId><version>1.7.2version>dependency>

然后编写一个工具类 IpUtils ,首先需要加载 ip2region.db 文件

static{dbPath=createFtlFileByFtlArray()+"ip2region.db";try{config=newDbConfig();}catch(DbMakerConfigExceptione){e.printStackTrace();}try{searcher=newDbSearcher(config,dbPath);}catch(FileNotFoundExceptione){e.printStackTrace();}}

在加载的时候,需要下载仓库中的 ip2region.db 文件,然后放到 resource 目录下

然后,通过内置的三种算法,分别转换用户 ip 地址

publicstaticStringgetCityInfo(Stringip){if(StringUtils.isEmpty(dbPath)){log.error("Error: Invalid ip2region.db file");returnnull;}if(config==null||searcher==null){log.error("Error: DbSearcher or DbConfig is null");returnnull;}//查询算法//B-tree, B树搜索(更快)intalgorithm=DbSearcher.BTREE_ALGORITHM;//Binary,使用二分搜索//DbSearcher.BINARY_ALGORITHM//Memory,加载内存(最快)//DbSearcher.MEMORY_ALGORITYMtry{// 使用静态代码块,减少文件读取操作//            DbConfig config = new DbConfig();//            DbSearcher searcher = new DbSearcher(config, dbPath);//define the methodMethodmethod=null;switch(algorithm){caseDbSearcher.BTREE_ALGORITHM:method=searcher.getClass().getMethod("btreeSearch",String.class);break;caseDbSearcher.BINARY_ALGORITHM:method=searcher.getClass().getMethod("binarySearch",String.class);break;caseDbSearcher.MEMORY_ALGORITYM:method=searcher.getClass().getMethod("memorySearch",String.class);break;default:}DataBlockdataBlock=null;if(Util.isIpAddress(ip)==false){System.out.println("Error: Invalid ip address");}dataBlock=(DataBlock)method.invoke(searcher,ip);StringipInfo=dataBlock.getRegion();if(!StringUtils.isEmpty(ipInfo)){ipInfo=ipInfo.replace("|0","");ipInfo=ipInfo.replace("0|","");}returnipInfo;}catch(Exceptione){e.printStackTrace();}returnnull;}

下面,我们编写 main 函数进行测试,发现可以正常的解析出 ip 信息

由于 ip 属地在国内的话,只会展示省份,而国外的话,只会展示国家。所以我们还需要对这个方法进行一下封装,得到获取 IP 属地的信息。

/*** 获取IP属地* @param ip* @return*/publicstaticStringgetIpPossession(Stringip){StringcityInfo=getCityInfo(ip);if(!StringUtils.isEmpty(cityInfo)){cityInfo=cityInfo.replace("|"," ");String[]cityList=cityInfo.split(" ");if(cityList.length>0){// 国内的显示到具体的省if("中国".equals(cityList[0])){if(cityList.length>1){returncityList[1];}}// 国外显示到国家returncityList[0];}}return"未知";}

下面,我们在找一个 国外的 IP 测试一下效果。可以看到已经能够正常的显示 IP 属地信息了~

到这里如果获取用户的 IP 属地已经完成啦,如果想要了解关于更多 ip2region 的功能,欢迎访问其 Github 地址进行学习。

项目地址:https://github.com/lionsoul2014/ip2region

码文不易,学到的小伙伴点个哦!

作者:叶秋学长链接:https://blog.csdn.net/m0_63722685/article/details/125698292?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-4-125698292-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-4-125698292-null-null.nonecase来源:CSDN

声明:本文部分素材转载自互联网,如有侵权立即删除 。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容