ip2region工具类

ip2region依赖ip2region.db文件,可以去作者的gitee/github项目的data包中去下载

作者的gitee:https://gitee.com/lionsoul/ip2region
作者的github:https://github.com/shaojjjin/ip2region

在这里插入图片描述
将db文件放在项目的resources下即可

package top.sclf.common.core.util;

import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbMakerConfigException;
import org.lionsoul.ip2region.DbSearcher;
import org.springframework.core.io.ClassPathResource;

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

/**
 * ip 转 ip归属地工具类
 * 核心对象是DbSearcher
 * 原理是有一个ip2region.db的sqlite数据库文件中保存了ip相关的归属地信息
 * 通过传入的ip到数据库中查询以得到归属地
 * <p>
 * 创建DbSearcher对象实际上是将db读取到byte[]中来解析的
 * DbSearcher的close是关闭对db文件的输入流
 * <p>
 * 该工具类通过getDbBinStr方法直接读取db到byte[]中,通过DbSearcher的含byte[]的构造器创建该对象,所以不需要关心DbSearcher的close
 * <p>
 * 提供reloadDb方法刷新DbSearcher的ip库
 *
 * @author zhangxing
 * @date 2021/5/11
 */
@Slf4j
public class Ip2regionUtils {

    private Ip2regionUtils() {
    }

    /**
     * 系统默认的ip库文件名
     */
    private static final String DB_NAME = "ip2region.db";

    /**
     * ip地址搜索器
     */
    private static DbSearcher ipSearcher;

    /**
     * ip库配置
     */
    private static DbConfig dbConfig;

    static {
        try {
            dbConfig = new DbConfig();
            initSearcher(getDbBinStr());
        } catch (DbMakerConfigException e) {
            log.error("ip2region config init fail", e);
        }
    }

    /**
     * ip转ip地址归属地
     *
     * @param ip ip地址
     * @return ip地址归属地
     */
    public static String ip2Addr(String ip) {
        if (ipSearcher == null) {
            return null;
        }
        try {
            DataBlock dataBlock = ipSearcher.memorySearch(ip);
            if (dataBlock != null) {
                return dataBlock.getRegion();
            }
        } catch (IOException e) {
            log.error("ip to addr exception", e);
        }
        return null;
    }

    /**
     * 重新加载指定的ip库文件
     * 如果后期ip库发生了更新,可以使用该方法更新ip库
     *
     * @param dbFile ip库文件
     */
    public static void reloadDb(File dbFile) {
        initSearcher(getDbBinStr(dbFile));
    }

    /**
     * 重新加载系统默认的ip库
     */
    public static void reloadDb() {
        initSearcher(getDbBinStr());
    }


    // ----------- 私有方法 -----------

    /**
     * 初始化一个ip地址搜索器
     *
     * @param dbBinStr ip库字节
     */
    private static void initSearcher(byte[] dbBinStr) {
        if (dbBinStr != null) {
            if (ipSearcher != null) {
                // 释放引用,让gc回收
                ipSearcher = null;
            }
            ipSearcher = new DbSearcher(dbConfig, dbBinStr);
        }
    }

    /**
     * 获取默认ip库的字节内容
     *
     * @return db字节内容
     */
    private static byte[] getDbBinStr() {
        ClassPathResource classPathResource = new ClassPathResource(DB_NAME);
        try {
            File file = classPathResource.getFile();
            return getDbBinStr(file);
        } catch (IOException e) {
            log.error("ip2region.db load fail", e);
        }
        return null;
    }

    /**
     * 获取指定ip库的字节内容
     *
     * @param dbFile ip库文件
     * @return db字节内容
     */
    private static byte[] getDbBinStr(File dbFile) {
        try {
            RandomAccessFile raf = new RandomAccessFile(dbFile, "r");
            byte[] dbBinStr = new byte[(int) raf.length()];
            raf.seek(0L);
            raf.readFully(dbBinStr, 0, dbBinStr.length);
            raf.close();
            return dbBinStr;
        } catch (IOException e) {
            log.error("ip2region.db load fail", e);
        }
        return null;
    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值