前言:ip2region 是一个离线IP地址定位库和IP定位数据管理框架,10微秒级别的查询效率。

github地址:https://github.com/lionsoul2014/ip2region

下载ip2region.xdb

springboot项目中在resources里面创建文件夹ipdb,把ip2region.xdb放进去

image-20240516092637886

maven

引入ip2region

1
2
3
4
5
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>2.6.5</version>
</dependency>

工具类

使用到的地方会创建基于内存的Searcher对象,没有使用该工具类,不会创建Searcher对象,项目停止的时候,判断是否存在Searcher,如果存在,关闭掉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import org.lionsoul.ip2region.xdb.Searcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;

import java.io.IOException;
import java.io.InputStream;

/**
* 按ip属地方法查询省市
*
* @Author: Chang
* @create: 2024/05/16 14:11
*/
public class IpRegionUtil {

private static final Logger logger = LoggerFactory.getLogger(IpRegionUtil.class);
private static final String IP_DATABASE_PATH = "/ipdb/ip2region.xdb";
private static byte[] dbBinStr;
private static Searcher searcher;

static {
try (InputStream inputStream = new ClassPathResource(IP_DATABASE_PATH).getInputStream()) {
// 从classpath中加载IP数据库文件到字节数组
dbBinStr = FileCopyUtils.copyToByteArray(inputStream);
// 创建基于内存的Searcher对象
searcher = Searcher.newWithBuffer(dbBinStr);
logger.info("IpRegionUtil 已创建 Searcher 对象");
} catch (IOException e) {
logger.error("初始化失败", e);
}
// 添加JVM关闭钩子,确保在JVM关闭时关闭Searcher对象
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
if (searcher != null) {
try {
searcher.close();
logger.info("IpRegionUtil Searcher 对象已关闭");
} catch (IOException e) {
logger.error("关闭失败", e);
}
}
}));
}

public static String getIpRegion(String ip) {
try {
return searcher.search(ip);
} catch (Exception e) {
logger.error("获取归属地信息失败", e);
return null;
}
}

public static String[] getIpProvinceAndCity(String cityInfo) {
if (cityInfo != null && !cityInfo.isEmpty()) {
String[] parts = cityInfo.split("\\|");
if (parts.length >= 4 && "中国".equals(parts[0])) {
return new String[]{parts[2], parts[3]}; // 省份和城市
} else if (parts.length >= 1) {
return new String[]{parts[0], ""}; // 国家
}
}
return new String[]{"", ""};
}

public static void main(String[] args) {
String ip = "112.18.112.162";
String cityInfo = getIpRegion(ip);
logger.info("归属地信息:{}", cityInfo);

String[] provinceAndCity = getIpProvinceAndCity(cityInfo);
String province = provinceAndCity[0];
String city = provinceAndCity[1];

logger.info("省份:{}", province);
logger.info("城市:{}", city);
}
}

效果展示

1
2
3
4
5
2024-05-16 14:39:08,890 INFO  com.listen.utils.IpRegionUtil 31 <clinit> - IpRegionUtil 已创建 Searcher 对象
2024-05-16 14:39:08,918 INFO com.listen.utils.IpRegionUtil 72 main - 归属地信息:中国|0|四川省|遂宁市|移动
2024-05-16 14:39:08,919 INFO com.listen.utils.IpRegionUtil 78 main - 省份:四川省
2024-05-16 14:39:08,919 INFO com.listen.utils.IpRegionUtil 79 main - 城市:遂宁市
2024-05-16 14:39:08,924 INFO com.listen.utils.IpRegionUtil 40 lambda$static$0 - IpRegionUtil Searcher 对象已关闭