| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- package com.ruoyi.common.utils.ip;
- import java.io.InputStream;
- import org.lionsoul.ip2region.service.Config;
- import org.lionsoul.ip2region.service.Ip2Region;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import com.ruoyi.common.utils.StringUtils;
- /**
- * ip2region 离线 IP 归属地查询工具。
- */
- public final class Ip2RegionUtils
- {
- private static final Logger log = LoggerFactory.getLogger(Ip2RegionUtils.class);
- private static final String XDB_CLASSPATH = "/ip2region/ip2region_v4.xdb";
- private static volatile Ip2Region ip2Region;
- private static volatile boolean initAttempted;
- private Ip2RegionUtils()
- {
- }
- /**
- * 查询 IP 归属地原始字符串,格式:Country|Province|City|ISP|Code。
- */
- public static String searchRegion(String ip)
- {
- if (StringUtils.isEmpty(ip))
- {
- return null;
- }
- Ip2Region service = getIp2Region();
- if (service == null)
- {
- return null;
- }
- try
- {
- return service.search(ip.trim());
- }
- catch (Exception ex)
- {
- log.warn("ip2region 查询失败 ip={}: {}", ip, ex.getMessage());
- return null;
- }
- }
- /**
- * 从 ip2region 结果中提取可用于区县展示的名称。
- */
- public static String extractDistrictName(String region)
- {
- if (StringUtils.isEmpty(region))
- {
- return null;
- }
- String[] parts = region.split("\\|");
- String city = parts.length > 2 ? nullIfZero(parts[2]) : null;
- String province = parts.length > 1 ? nullIfZero(parts[1]) : null;
- String country = parts.length > 0 ? nullIfZero(parts[0]) : null;
- return firstNonEmpty(city, province, country);
- }
- private static Ip2Region getIp2Region()
- {
- if (!initAttempted)
- {
- synchronized (Ip2RegionUtils.class)
- {
- if (!initAttempted)
- {
- initAttempted = true;
- ip2Region = createIp2Region();
- }
- }
- }
- return ip2Region;
- }
- private static Ip2Region createIp2Region()
- {
- try (InputStream inputStream = Ip2RegionUtils.class.getResourceAsStream(XDB_CLASSPATH))
- {
- if (inputStream == null)
- {
- log.warn("ip2region 数据库未找到: {}", XDB_CLASSPATH);
- return null;
- }
- Config v4Config = Config.custom()
- .setCachePolicy(Config.BufferCache)
- .setXdbInputStream(inputStream)
- .asV4();
- return Ip2Region.create(v4Config, null);
- }
- catch (Exception ex)
- {
- log.error("ip2region 初始化失败", ex);
- return null;
- }
- }
- private static String nullIfZero(String value)
- {
- if (StringUtils.isEmpty(value) || "0".equals(value.trim()))
- {
- return null;
- }
- return value.trim();
- }
- private static String firstNonEmpty(String... values)
- {
- if (values == null)
- {
- return null;
- }
- for (String value : values)
- {
- if (StringUtils.isNotEmpty(value))
- {
- return value;
- }
- }
- return null;
- }
- }
|