目前项目因为下游只有IP地址,需要获取省市区, 目前2中解决方案.

  1. 开源离线库

  2. 在线的API接口平台,(高德/百度/淘宝/腾讯等等)

项目目前选择ip2region开源离线库

ip2region:项目地址

https://github.com/lionsoul2014/ip2region

https://gitee.com/lionsoul/ip2region

ip.txt 转 xdb工具:

https://github.com/orestonce/Ip2regionTool

看iso下ip2region

项目源码:

https://kdocs.cn/l/cimQkEUnvwbc

ip.txt文件

https://kdocs.cn/l/cq7aBXeuz5id

xdb文件:

https://kdocs.cn/l/cozCtD1mwi6j

引入依赖

<dependency>
    <groupId>org.lionsoul</groupId>
    <artifactId>ip2region</artifactId>
    <version>2.7.0</version>
</dependency>

共用工具类

@Component
@Slf4j
public class Ip2regionUtils {
    private static Searcher searcher;

    /**
     * 根据 IP 地址从 ip2region.db 中获取地理位置
     * @param ip IP 地址
     * @return IP归属地
     */
    public static String getCityInfo(String ip) throws IOException {
        try {
            return searcher.search(ip);
        } catch (Exception e) {
            log.error("searcher fail!:{}",e.getMessage());
        }finally {
            searcher.close();
        }
        return null;
    }

    /**
     * 在服务启动时加载 ip2region.db 到内存中
     * 解决打包 jar 后找不到 ip2region.db 的问题
     * @throws Exception 出现异常应该直接抛出终止程序启动,避免后续 invoke 时出现更多错误
     */
    @PostConstruct
    private static void initIp2regionResource() {
        try {
            InputStream inputStream = new ClassPathResource("/ipdb/ip2region.xdb").getInputStream();
            byte[] dbBinStr = FileCopyUtils.copyToByteArray(inputStream);
            // 创建一个完全基于内存的查询对象
            searcher = Searcher.newWithBuffer(dbBinStr);
            log.info("ip2region.xdb load success!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据ip获取归属地
     *  //searchIpInfo 的数据格式: 国家|区域|省份|城市|ISP
     *  //192.168.31.160 0|0|0|内网IP|内网IP
     *  //47.52.236.180 中国|0|香港|0|阿里云
     *  //220.248.12.158 中国|0|上海|上海市|联通
     *  //164.114.53.60 美国|0|华盛顿|0|0  50.7.252.58
     * @param ip
     * @return 归属地
     */
    public static String getRegion(String ip){
        //使用 @PostConstruct 注解后不需要再调用
//        initIp2regionResource();
        try {
            String cityInfo = getCityInfo(ip);

            if(cityInfo==null) {
                log.error("cityInfo is null");
                return null;
            }
            String[] split = cityInfo.split("\\|");

            //--------------国内属地返回省份--------------
            if ("中国".equals(split[0])){
                if("0".equals(split[3])){
                    return split[0] + "-" + split[2];
                }
                return split[0] + "-" + split[2] + "-" + split[3];
            }
            //------------------内网 IP----------------
            if ("0".equals(split[0])){
                if ("内网IP".equals(split[3])){
                    return "内网IP";
                }
                else return null;
            }
            //--------------国外属地返回国家--------------
            else {
                return split[0] + "-" + split[2];
            }
        } catch (IOException e) {
            log.error("获取ip归属地异常:{}",e.getMessage());
            return null;
        }
    }

}

测试方法

String result = Ip2regionUtils.getRegion("171.11.6.72");
System.out.println(result);

-----
中国-河南省-郑州市
String result = Ip2regionUtils.getCityInfo("171.11.6.72");
System.out.println(result);

-----
中国|0|河南省|郑州市|电信

文章作者: 刘同学
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 刘同学的小站
后端 Java
喜欢就支持一下吧