强大的离线IP地址定位库ip2region获取地理信息

359 阅读1分钟

一、前言

在项目上有时候需要获取对象IP的地理位置,但有时在没有外网的情况下我们是无法去调用外部接口去获取的,那么这时就需要我们能通过本地工具去获取IP的地理位置,ip2region.db提供了强大的离线IP地理位置的获取,它的准确率能到达99.9%,0.0x毫秒级查询,ip2region.db数据库只有数MB,提供了java、php、c、python、nodejs、golang、c#等查询绑定和Binary,B树,内存三种查询算法。

二、依赖引入

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

三、下载ip2region.db

地址:通过gitee.com/lionsoul/ip…下载,项目下存放位置可以选择任意位置放置/存放在项目src根目录下

四、使用方式IpLocationUtils

package cn.com.ebidding.web.api.utils;

import org.lionsoul.ip2region.*;
import org.net.plat4j.sr.core.base.BaseException;
import org.net.plat4j.sr.core.utils.ExceptionUtils;
import org.net.plat4j.sr.core.utils.LogHelper;

import java.io.File;
import java.io.IOException;

/**
 * @author :骑着蚂蚁去上天
 * @date :Created in 10:09 2021/8/26
 * @description:获取ip地理位置
 * @modified By:
 * @Version: V4.2
 */
public class IpLocationUtils {

    private static final LogHelper LOGGER = new LogHelper(IpLocationUtils.class);

    private static final String UNKOWN_ADDRESS = "未知位置";

    private static final String INTRANET_IP = "内网IP";


    /**
     * 获取 IP 地理位置
     * @param ip
     * @return
     */
    public static String getIpLocation(String ip) {
        return getIpLocation(ip, DbSearcher.BTREE_ALGORITHM);
    }

    /**
     * 获取 IP 地理位置
     * @param ip
     * @param algorithm
     * @see DbSearcher
     * DbSearcher.BTREE_ALGORITHM; //B-tree
     * DbSearcher.BINARY_ALGORITHM //Binary
     * DbSearcher.MEMORY_ALGORITYM //Memory
     * @return 国家|区域|省份|城市|ISP
     */
    private static String getIpLocation(String ip, int algorithm) {
        DataBlock dataBlock = null;
        StringBuffer ipLocation = new StringBuffer();
        try {
            if (!Util.isIpAddress(ip)) {
                LOGGER.error("错误格式的ip地址: {}", ip);
                return UNKOWN_ADDRESS;
            }
            // 获取 HttpServletRequest
            String dbPath = IpLocationUtils.class.getClassLoader().getResource("/ip2region.db").getPath();
            LOGGER.info("======获取到文件路径为:【{0}】", dbPath);
            // 获取 ip 地址库
            File dbFile = new File(dbPath);
            if (!dbFile.exists()) {
                LOGGER.error("========IP地址库文件不存在,路径为:【{0}】", dbPath);
                return UNKOWN_ADDRESS;
            }
            DbSearcher searcher = new DbSearcher(new DbConfig(), dbPath);
            switch (algorithm) {
                case DbSearcher.BTREE_ALGORITHM:
                    dataBlock = searcher.btreeSearch(ip);
                    break;
                case DbSearcher.BINARY_ALGORITHM:
                    dataBlock = searcher.binarySearch(ip);
                    break;
                case DbSearcher.MEMORY_ALGORITYM:
                    dataBlock = searcher.memorySearch(ip);
                    break;
                default:
                    LOGGER.error("=======未传入正确的查询算法");
                    return UNKOWN_ADDRESS;
            }
            String[] split = dataBlock.getRegion().split("\\|");
            if (!dataBlock.getRegion().contains(INTRANET_IP)) {
                ipLocation.append(split[0]).append("-").append(split[2]).append("-").append(split[3]);
            } else {
                ipLocation.append(split[3]);
            }
            searcher.close();
        } catch (IOException e) {
            LOGGER.error("====== IOException ======【{0}】", ExceptionUtils.conventStringException(e));
            throw new BaseException(e);
        } catch (DbMakerConfigException e) {
            LOGGER.error("====== DbMakerConfigException ======【{0}】", ExceptionUtils.conventStringException(e));
            throw new BaseException(e);
        }
        return ipLocation.toString();
    }


    public static void main(String[] args) {
        System.out.println(getIpLocation("106.35.112.88"));
        System.out.println(getIpLocation("192.168.43.151"));
    }
}