使用强大的离线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月前
|
搜索推荐 Java 定位技术
Java实现利用GeoLite2-City.mmdb根据IP定位城市的方法
在城市,国家,地区等地理位置数据获取之后,你可以依指定的业务需求,来进行进一步的数据处理。例如,你可以设计一个应用,根据用户的 IP 地址来个性化地展示内容,或者用于分析网络请求的来源等。
1170 20
|
算法 JavaScript Java
一个还不错的离线 IP 地址定位库,99.9% 准确率
一个还不错的离线 IP 地址定位库,99.9% 准确率
699 0
|
12月前
|
API 定位技术
查IP[查指定IP归属地]免费API接口教程
该API用于查询指定IPv4地址的归属地信息,支持POST和GET请求。需提供用户ID和KEY,可选填查询IP,默认为请求接口IP。返回信息包括状态码、地理位置及运营商等。示例请求和响应详见文档。
1793 3
|
存储 Java 定位技术
获取ip所在城市
本文介绍了如何在SpringBoot应用中通过IP地址快速获取用户的国家、省份和城市信息。首先,通过引入GeoLite2 City数据库并整合相关依赖,接着下载并配置GeoLite2 City数据库文件。然后,创建地址获取工具类和Controller接口,最后进行测试以确保功能正常。此方法简单高效,适用于多种应用场景。
|
定位技术
获取本地IP以及地理位置
获取本地IP以及地理位置
|
存储 Java 定位技术
【Java】根据IP地址获取省市
【Java】根据IP地址获取省市
1096 1
|
JSON 定位技术 数据格式
根据现有IP地址获取其地理位置(省份,城市等)的方法
根据现有IP地址获取其地理位置(省份,城市等)的方法
1514 0
|
缓存 Java Maven
ip解析ip2region
ip解析ip2region
328 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,用户手机里
7295 1
|
Web App开发 Linux Android开发
常见浏览器User-Agent大全
下面是工作中需要用到的常见浏览器User-Agent字符串的收集整理,不断更新中。 OperaMozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.
12685 2