目录

  • 1. ip2region 简介
  • 2. 使用步骤
    • 2.1 下载资源
    • 2.2 引入依赖
    • 2.3 编写工具类
      • 2.3.1 获取 IP 地址
      • 2.3.2 根据 IP 地址获取 IP 归属地
      • 2.3.3 完整代码
    • 2.4 结果测试

1. ip2region 简介

ip2region 是一个离线IP地址定位库和IP定位数据管理框架,能实现10微秒级别的查询效率,提供了众多主流编程语言的xdb数据生成和查询客户端实现。

每个 ip 数据段的 region 信息都固定了格式:国家|区域|省份|城市|ISP,只有中国的数据绝大部分精确到了城市,其他国家部分数据只能定位到国家,后前的选项全部是0。

下载地址:

  • githhub
  • gitee

2. 使用步骤

2.1 下载资源

下载 ip2region 后,将ip2region.xdb (如下图)复制到项目的resources/ipdb文件夹下。

2.2 引入依赖

<dependency><groupId>org.lionsoul</groupId><artifactId>ip2region</artifactId><version>2.6.5</version>
</dependency>

2.3 编写工具类

2.3.1 获取 IP 地址

根据用户请求获取用户真实 IP 地址:

/*** 在 Nginx 等代理之后获取用户真实 IP 地址* @return 用户的真实 IP 地址*/
public static String getIpAddress(HttpServletRequest request) {if (request == null) {return null;}String ip = request.getHeader("x-forwarded-for");if (isIpaddress(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (isIpaddress(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (isIpaddress(ip)) {ip = request.getHeader("HTTP_CLIENT_IP");}if (isIpaddress(ip)) {ip = request.getHeader("HTTP_X_FORWARDED_FOR");}if (isIpaddress(ip)) {ip = request.getRemoteAddr();if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {//根据网卡取本机配置的IPtry {InetAddress inet = InetAddress.getLocalHost();ip = inet.getHostAddress();} catch (UnknownHostException e) {e.printStackTrace();}}}return ip;
}

如果有使用 Nginx 等代理服务器则需进行配置[云笔记系统没有配置也可以正常使用],例如在nginx.conf文件中进行如下配置1

location / {proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;
}

其中

  • Host:获取客户端(client)的真实域名和端口号
  • X-Real-IP:获取客户端真实 IP 地址
  • X-Forwarded-For:也是获取客户端真实 IP 地址,如果有多层代理时会获取客户端真实 IP 及每层代理服务器的 IP 地址
  • X-Forwarded-Proto:获取客户端的真实协议(如 http、https)

  1. getRemoteAddr()用于获取没有代理服务器情况下用户的 IP 地址2
  2. 当用户的请求经过一个代理服务器后到达最终服务器,此时在最终服务器端通过getRemoteAddr()只能得到代理服务器的 IP 地址,通过在代理服务器中配置proxy_set_header X-Real-IP $remote_addr,最终的服务器可以通过X-Real-IP获取用户的真实 IP 地址。
  3. 当用户的请求经过多个代理服务器后到达最终服务器时,配置proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for后可通过X-Forwarded-For获取用户真实 IP 地址(请求通过第一台 nginx时:X-Forwarded-For = X-Real-IP = 用户真实 IP 地址;请求通过第二台 nginx 时:X-Forwarded-For = 用户真实 IP 地址, X-Real-IP = 上一台 nginx 的 IP 地址 )。
  4. 获取客户端的IP地址不仅可以通过proxy_set_header X-real-ip $remote_addr;获取,也可以通过proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;获取。

2.3.2 根据 IP 地址获取 IP 归属地

/*** 根据 IP 地址返回归属地,国内返回但省份,国外返回到国家* @param ip IP 地址* @return IP 归属地*/
public static String getIpRegion(String ip) {initIp2regionResource();HashMap<String, String> cityInfo = new HashMap<>();String searchIpInfo = getCityInfo(ip);//-------------------------------------------------------//searchIpInfo 的数据格式: 国家|区域|省份|城市|ISP//192.168.31.160 0|0|0|内网IP|内网IP//47.52.236.180 中国|0|香港|0|阿里云//220.248.12.158 中国|0|上海|上海市|联通//164.114.53.60 美国|0|华盛顿|0|0//-------------------------------------------------------String[] splitIpInfo = searchIpInfo.split("\\|");cityInfo.put("ip",ip);cityInfo.put("searchInfo", searchIpInfo);cityInfo.put("country",splitIpInfo[0]);cityInfo.put("region",splitIpInfo[1]);cityInfo.put("province",splitIpInfo[2]);cityInfo.put("city",splitIpInfo[3]);cityInfo.put("ISP",splitIpInfo[3]);//--------------国内属地返回省份--------------if ("中国".equals(cityInfo.get("country"))){return cityInfo.get("province");}//------------------内网 IP----------------if ("0".equals(cityInfo.get("country"))){if ("内网IP".equals(cityInfo.get("ISP"))){return "";}else return "";}//--------------国外属地返回国家--------------else {return cityInfo.get("country");}
}

2.3.3 完整代码

IPUtils.java3:

import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;@Component
public class IPUtils {private static Searcher searcher;/*** 在 Nginx 等代理之后获取用户真实 IP 地址* @return 用户的真实 IP 地址*/public static String getIpAddress(HttpServletRequest request) {if (request == null) {return null;}String ip = request.getHeader("x-forwarded-for");if (isIpaddress(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (isIpaddress(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (isIpaddress(ip)) {ip = request.getHeader("HTTP_CLIENT_IP");}if (isIpaddress(ip)) {ip = request.getHeader("HTTP_X_FORWARDED_FOR");}if (isIpaddress(ip)) {ip = request.getRemoteAddr();if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {//根据网卡取本机配置的IPtry {InetAddress inet = InetAddress.getLocalHost();ip = inet.getHostAddress();} catch (UnknownHostException e) {e.printStackTrace();}}}return ip;}/*** 判断是否为 IP 地址* @param ip  IP 地址*/public static boolean isIpaddress(String ip) {return ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip);}/*** 获取本地 IP 地址* @return 本地 IP 地址*/public static String getHostIp() {try {return InetAddress.getLocalHost().getHostAddress();} catch (UnknownHostException e) {e.printStackTrace();}return "127.0.0.1";}/*** 获取主机名* @return 本地主机名*/public static String getHostName() {try {return InetAddress.getLocalHost().getHostName();} catch (UnknownHostException e) {e.printStackTrace();}return "未知";}/*** 根据 IP 地址从 ip2region.db 中获取地理位置* @param ip IP 地址* @return IP归属地*/public static String getCityInfo(String ip) {try {return searcher.search(ip);} catch (Exception e) {e.printStackTrace();}return null;}/*** 在服务启动时加载 ip2region.db 到内存中* 解决打包 jar 后找不到 ip2region.db 的问题* @throws Exception 出现异常应该直接抛出终止程序启动,避免后续 invoke 时出现更多错误*/@PostConstructprivate static void initIp2regionResource() {try {InputStream inputStream = new ClassPathResource("/ipdb/ip2region.xdb").getInputStream();byte[] dbBinStr = FileCopyUtils.copyToByteArray(inputStream);// 创建一个完全基于内存的查询对象searcher = Searcher.newWithBuffer(dbBinStr);} catch (Exception e) {e.printStackTrace();}}/*** 根据 IP 地址返回归属地,国内返回但省份,国外返回到国家* @param ip IP 地址* @return IP 归属地*/public static String getIpRegion(String ip) {initIp2regionResource();HashMap<String, String> cityInfo = new HashMap<>();String searchIpInfo = getCityInfo(ip);//-------------------------------------------------------//searchIpInfo 的数据格式: 国家|区域|省份|城市|ISP//192.168.31.160 0|0|0|内网IP|内网IP//47.52.236.180 中国|0|香港|0|阿里云//220.248.12.158 中国|0|上海|上海市|联通//164.114.53.60 美国|0|华盛顿|0|0//-------------------------------------------------------String[] splitIpInfo = searchIpInfo.split("\\|");cityInfo.put("ip",ip);cityInfo.put("searchInfo", searchIpInfo);cityInfo.put("country",splitIpInfo[0]);cityInfo.put("region",splitIpInfo[1]);cityInfo.put("province",splitIpInfo[2]);cityInfo.put("city",splitIpInfo[3]);cityInfo.put("ISP",splitIpInfo[3]);//--------------国内属地返回省份--------------if ("中国".equals(cityInfo.get("country"))){return cityInfo.get("province");}//------------------内网 IP----------------if ("0".equals(cityInfo.get("country"))){if ("内网IP".equals(cityInfo.get("ISP"))){return "";}else return "";}//--------------国外属地返回国家--------------else {return cityInfo.get("country");}}}

2.4 结果测试

测试代码:

@Test
public void test04(){System.out.println(IPUtils.getIpRegion("117.28.182.162"));
}

测试结果:

福建省

  1. 一文彻底搞懂Nginx的.conf文件路径配置 ↩︎

  2. nginx获取代理服务ip及客户端真实ip ↩︎

  3. SpringBoot 整合 ip2region2.x 工具类 ↩︎

使用 ip2region 获取用户的 IP 归属地相关推荐

  1. php 获取用户登录IP 及 IP归属地

    php 获取用户登录IP 及 IP归属地 获取登录 IP 代码如下 ↓ function getIP(){$onlineip;if(getenv('HTTP_CLIENT_IP')) {$online ...

  2. php查询ip归属地api接口_【php】利用新浪api接口与php获取远程数据的方法,获取IP地址,并获取相应的IP归属地...

    本文与<[Servlet]Javaweb中,利用新浪api接口,获取IP地址,并获取相应的IP归属地>(点击打开链接)为姊妹篇,只是后端编程语言换成了php. 做出同样的效果,打开页面,得 ...

  3. php新浪获取ip接口,【php】利用新浪api接口与php获取远程数据的步骤,获取IP地址,并获取相应的IP归属地...

    [php]利用新浪api接口与php获取远程数据的方法,获取IP地址,并获取相应的IP归属地 本文与<[Servlet]Javaweb中,利用新浪api接口,获取IP地址,并获取相应的IP归属地 ...

  4. php 获取用户的IP、地址、来源

    js方法获取用户的 ip 和 地址 <script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> ...

  5. PHP获取用户真实IP地址

    PHP获取用户真实IP地址 <?phpfunction getRealIpAddr() { if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip=$_SER ...

  6. nginx反向代理获取用户真实ip

    nginx做反向代理时,默认的配置后端获取到的ip都是来自于nginx,如何转发用户的真实ip到后端程序呢?如是是java后端,用request.getRemoteAddr();获取到的是nginx的 ...

  7. php获取客户端ip端口,Phpwind获取用户真实IP

    Phpwind获取用户真实IP 使用nat123端口映射后,可能会遇到phpwind网站无法获取用户真实IP的情况,对应解决方法有下. phpwind8.5的方法: 修改 /require/commo ...

  8. nginx利用反向代理实现获取用户真实ip

    我们访问互联网上的服务时,大多数时,客户端并不是直接访问到服务端的,而是客户端首先请求到反向代理,反向代理再转发到服务端实现服务访问,通过反向代理实现路由/负载均衡等策略.这样在服务端拿到的客户端IP ...

  9. JAVA:获取用户访问ip地址

    获取用户真实IP地址:不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址: 可是,如果通过了多级反向代理的话,X-Forwarded-For的值 ...

最新文章

  1. NLP为RPA带来了什么价值?
  2. 《强化学习周刊》第10期:强化学习应用之计算机视觉
  3. MSSql存储过程高效应用
  4. Android 学习笔记 BroadcastReceiver广播...
  5. Android开发-屏幕常亮的方法
  6. 计算机联网实验步骤,计算机网络技术实验操作过程.doc
  7. 格式化数字字符串输出的一个小技巧
  8. HTTP Error 415: Unsupported Media Type! 这个错误
  9. 理解 Delphi 的类(十一) - 深入类中的方法[12] - 消息方法
  10. ios控件 UIViewController
  11. Android应用开发的一些思考
  12. The processing instruction target matching [xX][mM][lL] is not allowed.
  13. matlab平稳性检验实例
  14. DirectX简单的FBX文件加载(网格MESH)
  15. Python 的输出矩阵的一些常用设置
  16. mysql随机生成中文姓名_编写mysql函数 随机生成中文姓名
  17. 逐点比较法直线插补MATLAB
  18. python爬取上海高级人民法院网开庭公告数据
  19. 重构kz-admin
  20. 洛谷 2184 贪婪大陆

热门文章

  1. wslregisterdistribution failed with error: 0x80070005
  2. sublime3激活方式
  3. C++入门教程(十一、宏)
  4. 为了在上海租房,我用python连夜爬了20000多条房源信息
  5. ios相关证书申请完整流程
  6. BZOJ 2716 Violet 3 天使玩偶
  7. MYSQL查询大于创建时间一小时的数据
  8. 中国网银安全分析:动态密码锁
  9. win10、pycharm、Intellij IDEA、jupyter及高斯键盘常用快捷键、指令
  10. spring listener详尽篇