一、前言
在项目上有时候需要获取对象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"));
}
}