使用强大的离线IP地址定位库ip2region获取城市信息

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

一、简介

   ip2region - 准确率99.9%的离线IP地址定位库,0.0x毫秒级查询,ip2region.db数据库只有数MB,提供了java、php、c、python、nodejs、golang、c#等查询绑定和Binary,B树,内存三种查询算法。
在这里插入图片描述

二、ip2region的使用

1、引入依赖

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

2、下载ip2region.db

这个可以在gitee仓库(https://gitee.com/lionsoul/ip2region)下载,在项目的data目录下。

3、IpUtils工具类

  我封装了一个IpUtils工具类,主要有两个方法,一个是去获取请求中的真实客户端ip,一个是通过ip获取城市信息。

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * IP城市定位
 *
 * @author
 * @Date 2021/1/1
 */
@Slf4j
public class IPUtils {
    private static final String DB_PATH = "C:\\Users\\yanyunfan\\Downloads\\ip2region.db";
    private static final String DEFAULT_CITY_NAME = "未知";

    /**
     * 获取城市信息
     *
     * @param ip        ip
     * @param algorithm 算法
     * @return
     */
    public static String getIpAddress(String ip, int algorithm) {
        if (Util.isIpAddress(ip)) {
            return DEFAULT_CITY_NAME;
        } else if ("127.0.0.1".equals(ip) || StringUtils.startsWith(ip, "192.168")) {
            return "内网IP";
        }

        // 查询算法B-tree, Binary, Memory
        DbSearcher searcher = null;
        try {
            DbConfig config = new DbConfig();
            searcher = new DbSearcher(config, DB_PATH);

            Method method;
            switch (algorithm) {
                case DbSearcher.BTREE_ALGORITHM:
                    method = searcher.getClass().getMethod("btreeSearch", String.class);
                    break;
                case DbSearcher.BINARY_ALGORITHM:
                    method = searcher.getClass().getMethod("binarySearch", String.class);
                    break;
                case DbSearcher.MEMORY_ALGORITYM:
                default:
                    method = searcher.getClass().getMethod("memorySearch", String.class);
                    break;
            }

            DataBlock dataBlock = (DataBlock) method.invoke(searcher, ip);
            List<String> list = Arrays.asList(dataBlock.getRegion().split("\\|")).stream().filter(s -> !"0".equals(s)).collect(Collectors.toList());
            String ipAddress = StringUtils.join(list, ",");
            return ipAddress;
        } catch (Exception e) {
            log.error("获取城市信息失败:", e);
        } finally {
            try {
                searcher.close();
            } catch (IOException e) {
            }
        }
        return DEFAULT_CITY_NAME;
    }

    /**
     * 获取客户端ip
     *
     * @param request 请求
     * @return
     */
    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        } else if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        } else if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        } else if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        } else if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static void main(String[] args) {
        String ip = "1.80.0.0";
        String cityIpString = getIpAddress(ip, 2);
        System.out.println(cityIpString);
    }
}

控制台输出:

中国,陕西省,西安市,电信
相关文章
|
6月前
|
搜索推荐 定位技术
如何快速查询自己的IP地址?
IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
如何快速查询自己的IP地址?
|
6月前
|
算法 JavaScript Java
一个还不错的离线 IP 地址定位库,99.9% 准确率
一个还不错的离线 IP 地址定位库,99.9% 准确率
419 0
|
Java 定位技术 数据库
通过ip获取地理位置信息
通过ip获取地理位置信息
629 0
|
定位技术 API
天地图API接口地址批量转换为经纬度的解决方案
天地图API接口地址批量转换为经纬度的解决方案
317 0
|
监控 大数据 定位技术
|
定位技术 开发工具
openGPS.cn - 基于ip的定位技术分享,高精度IP定位
利用业余时间自己做了个网站,集成了几个第三方数据源,对比IP地址查询的功能: 普通IP定位:https://www.opengps.cn/Data/IP/IPSearch.aspx 高精度IP定位:https://www.opengps.cn/Data/IP/IPHighAccuracy.aspx 其中,高精度IP定位为百度提供的服务,个人理解其工作原理应当是: 1,用户手机里
6770 1
|
网络架构
IP 地址规划实例
IP 地址规划实例小知识
405 0
IP 地址规划实例
|
网络协议 网络架构
IP数据报分析
IP数据报抓包分析
727 2
IP数据报分析
|
数据采集 Python
Python爬虫系列3-通过Ip地址定位目标所在区域
在现如今的互联网时代,我们越来越依赖网络,甚至网络已经融入了我们的日常生活,甚至没有办法想象如果没有了网络,会造成什么样的情景?。。。
Python爬虫系列3-通过Ip地址定位目标所在区域
|
前端开发
前端IP位置定位以及访问日志问题解决
前端IP位置定位以及访问日志问题解决