使用强大的离线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);
    }
}

控制台输出:

中国,陕西省,西安市,电信
相关文章
Java 通过IP获取对应的国家省份城市经纬度(离线文件方案)
一. 除了调用接口查询城市, 还可以通过离线文件查询城市, 使用GeoLite2 City库 二. 离线库下载地址: https://dev.maxmind.com/geoip/geoip2/geolite2/ 点击如下位置下载压缩文件 文件解压后有一个文件名为GeoLite2-City.
|
9月前
|
搜索推荐 Java 定位技术
Java实现利用GeoLite2-City.mmdb根据IP定位城市的方法
在城市,国家,地区等地理位置数据获取之后,你可以依指定的业务需求,来进行进一步的数据处理。例如,你可以设计一个应用,根据用户的 IP 地址来个性化地展示内容,或者用于分析网络请求的来源等。
1651 20
|
算法 JavaScript Java
一个还不错的离线 IP 地址定位库,99.9% 准确率
一个还不错的离线 IP 地址定位库,99.9% 准确率
931 0
|
存储 Java 定位技术
获取ip所在城市
本文介绍了如何在SpringBoot应用中通过IP地址快速获取用户的国家、省份和城市信息。首先,通过引入GeoLite2 City数据库并整合相关依赖,接着下载并配置GeoLite2 City数据库文件。然后,创建地址获取工具类和Controller接口,最后进行测试以确保功能正常。此方法简单高效,适用于多种应用场景。
|
弹性计算 缓存 Linux
私网环境下使用云效流水线进行 CI/CD的方法
云效流水线可以托管用户的私网环境内的机器,并将构建任务调度到这些机器上,从而确保整个构建过程,和代码库和制品库的交互在私网环境下进行。
47056 18
|
定位技术
获取本地IP以及地理位置
获取本地IP以及地理位置
|
存储 Java 定位技术
【Java】根据IP地址获取省市
【Java】根据IP地址获取省市
1379 1
|
定位技术 API
通过经纬度获得地址与城市名称(原创)
通过经纬度获得地址与城市名称(原创)
576 3
|
JSON 定位技术 数据格式
根据现有IP地址获取其地理位置(省份,城市等)的方法
根据现有IP地址获取其地理位置(省份,城市等)的方法
1666 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,用户手机里
7435 1