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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| package com.bluedeer.wechat.utils;
import org.apache.commons.lang3.ArrayUtils; import org.lionsoul.ip2region.xdb.Searcher; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;
import lombok.Data; import lombok.extern.slf4j.Slf4j;
/** * @desc ip工具类 * @author RenJie * @date 2024-06-24 */ @Slf4j @Component public class IpUtils {
public static byte[] IP2REGION_VINDEX;// ip2region的缓存文件
private static String ipRegionPath;
@SuppressWarnings("static-access") @Value("${ip2region.path}") public void setIpRegionPath(String ipRegionPath) { this.ipRegionPath = ipRegionPath; }
public @Data static class IpRegion { public Boolean isSuccess;// ip转换地区是否成功 public String region;// 地区 public String country;// 国家 public String province;// 省份 public String city;// 城市 public String internet;// 网络 public String ip;// ip地址 public String message;// 错误信息 } /** * 初始化正确返回值 * * @param region 解析的区域 * @param country 国家 * @param province 省份 * @param city 城市 * @param internet 网络 * @param ip ip地址 * @return */ public static IpRegion initIpRegionSuccess(String region, String country, String province, String city, String internet, String ip) { IpRegion ipm = new IpRegion(); ipm.setCity(city); ipm.setCountry(country); ipm.setMessage("解析成功"); ipm.setIsSuccess(true); ipm.setIp(ip); ipm.setRegion(region); ipm.setProvince(province); ipm.setInternet(internet); return ipm; }
/** * 初始化错误的返回值 * * @param ip ip地址 * @param message 错误内容 * @return */ public static IpRegion initIpRegionError(String ip, String message) { IpRegion ipm = new IpRegion(); ipm.setCity(""); ipm.setCountry(""); ipm.setMessage(message); ipm.setIsSuccess(false); ipm.setIp(ip); ipm.setRegion(""); ipm.setProvince(""); return ipm; } /** * @desc ip转换城市 * @param ip * @return */ public static IpRegion ip2region(String ip) { log.info("ip:" + ip); byte[] vIndex = loadVIndex(); // 2、使用全局的 vIndex 创建带 VectorIndex 缓存的查询对象。 Searcher searcher; try { searcher = Searcher.newWithVectorIndex(ipRegionPath, vIndex); } catch (Exception e) { log.error("创建Searcher失败", e); return initIpRegionError(ip, "创建Searcher失败"); }
// 3、查询 try { String region = searcher.search(ip); log.info("region:" + region); // 中国|0|山东省|济南市|电信 String[] rg = region.split("\\|"); log.info("rg:" + ArrayUtils.toString(rg)); String country = rg[0].equals("0") ? "" : rg[0]; String province = rg[2].equals("0") ? "" : rg[2]; String city = rg[3].equals("0") ? "" : rg[3]; String internet = rg[4].equals("0") ? "" : rg[4]; // 4、关闭资源 searcher.close(); return initIpRegionSuccess(region, country, province, city, internet, ip);
} catch (Exception e) { log.info("解析结果异常", e); return initIpRegionError(ip, "解析结果异常"); } // 备注:每个线程需要单独创建一个独立的 Searcher 对象,但是都共享全局的制度 vIndex 缓存。 } /** * @desc 加载ip2region.xdb文件 * @return */ public static byte[] loadVIndex() { if (IP2REGION_VINDEX != null) { return IP2REGION_VINDEX; } else { byte[] vIndex; try { vIndex = Searcher.loadVectorIndexFromFile(ipRegionPath); IP2REGION_VINDEX = vIndex; } catch (Exception e) { log.info("failed to load vector index from `%s`: %s\n", ipRegionPath, e); return null; } return IP2REGION_VINDEX; } }
public static void main(String[] args) { String ip = "127.0.0.1"; ip2region(ip); } }
|