SpringBoot集成ip2region2.X
离线IP地址定位库主要用于内网或想减少对外访问http带来的资源消耗。本博客使用的是ip2region + 在线获取。
ip2region总体分为两个大版本:
1.x:提供三种算法,其中内存查询速度在0.1x毫秒级别,离线库文件ip2region.db
2.x:同样提供三种算法,其中内存查询速度在微秒级别,离线库文件ip2region.xdb
本篇文章将以2.X版本进行演示。
基本配置
1、离线库下载:
github:https://github.com/lionsoul2014/ip2region/tree/master/data
将文件下载完成后,放到项目的resource目录下新建的ip2region目录中:
2、POM文件:
<!-- 离线IP地址定位库 -->
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>2.6.5</version>
</dependency>
<!-- 识别xdb文件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>xdb</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
AddressUtils
import com.alibaba.fastjson.JSONObject;
import com.xffjs.common.utils.http.HttpUtils;
import com.xffjs.framework.config.SystemConfig;
import org.apache.commons.io.FileUtils;
import org.apache.shiro.io.ResourceUtils;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.lang.reflect.Method;
/**
* @className: AddressUtils
* @description: ip地址获取位置工具类
* @author: xiaofei
* @create: 2021年04月11日
*/
public class AddressUtils {
private final static Logger LOGGER = LoggerFactory.getLogger(AddressUtils.class);
/**
* 可参考下面文章进行修改: https://blog.xffjs.com/f/article/93.html
*/
public static final String IP_URL4 = "";
/**
* 根据ip获取位置
*
* @param ip
* @return 国家|区域|省份|城市|ISP_
*/
public static String getRealAddressByIp(String ip) {
long startTime = System.currentTimeMillis();
String address = "";
// 内网不查询
if (IpUtils.internalIp(ip)) {
return "内网IP";
}
address = getRegion(ip);
if (StringUtils.isEmpty(address)) {
if (SystemConfig.isAddressEnabled()) {
String rspStr = HttpUtils.sendPost(IP_URL4, "ip=" + ip);
if (StringUtils.isEmpty(rspStr)) {
LOGGER.error("获取地理位置异常 {}", ip);
return address;
}
JSONObject obj = JSONObject.parseObject(rspStr);
String country = obj.getString("country");
String region = obj.getString("province");
String city = obj.getString("city");
String isp = obj.getString("isp");
if (address.equals(region) && address.equals(city)) {
return obj.getString("country") + obj.getString("isp") + "流量";
}
address = country + "|" + "999|" + region + "|" + city + "|" + isp;
}
}
long endTime = System.currentTimeMillis();
LOGGER.debug("获取ip位置耗时:[{}] ", endTime - startTime);
return address;
}
//********************************* 根据ip离线查询地址Star ***********************************************************
protected static Searcher searcher;
static {
InputStream resourceAsStream = AddressUtils.class.getClassLoader().getResourceAsStream("ip2region/ip2region.xdb");
if (resourceAsStream != null) {
byte[] cBuff;
try {
cBuff = FileCopyUtils.copyToByteArray(resourceAsStream);
searcher = Searcher.newWithBuffer(cBuff);
} catch (IOException e) {
LOGGER.error("AddressUtils-error:{}", e);
} finally {
try {
resourceAsStream.close();
} catch (Exception e) {
LOGGER.error("AddressUtils-error:{}", e);
}
}
}
}
public static Searcher getSearch() {
return searcher;
}
/**
* 离线根据ip获取位置--2.X
*
* @param ip
* @return 国家|区域|省份|城市|ISP_
*/
public static String getRegion(String ip) {
long ipLong = ipToLong(ip);
try {
String search = searcher.search(ipLong);
if (StringUtils.isNotEmpty(search)) {
return search;
}
} catch (Exception e) {
LOGGER.error("AddressUtils-error:{}", e);
}
return StringUtils.EMPTY;
}
//********************************* 根据ip离线查询地址End ***********************************************************
/**
* ip转long
*
* @param ip
* @return long
*/
public static long ipToLong(String ip) {
String[] split = ip.split("\\.");
long i1 = 0L;
i1 += (long) Integer.parseInt(split[0]) << 24;
i1 += (long) Integer.parseInt(split[1]) << 16;
i1 += (long) Integer.parseInt(split[2]) << 8;
return i1 + Integer.parseInt(split[3]);
}
}
打赏
当前共有 3 条评论
刚刚测试基本都在10毫秒以内,但是它这个不支持IPV6。
那还是非常快的,值得拥有。你网站里输出的结果就挺好的。
请问一般查找一个IP地址耗时多少,比如说下面这行代码执行的时间是? LOGGER.debug("获取ip位置耗时:[{}] ", endTime - startTime);
刚刚测试基本都在10毫秒以内,但是它这个不支持IPV6。
请问一般查找一个IP地址耗时多少,比如说下面这行代码执行的时间是? LOGGER.debug("获取ip位置耗时:[{}] ", endTime - startTime);