通过ip2region.xdb获取IP属地

实现前提:

1:下载ip2region.xdb文件
lionsoul2014/ip2region:Ip2region (2.0 - xdb) 是一个离线IP地址管理与定位框架,能够支持数十亿级别的数据段,并实现十微秒级的搜索性能。它为多种编程语言提供了xdb引擎实现。_Go - GitCode开源社区Ip2region (2.0 - xdb) 是一个离线IP地址管理与定位框架,能够支持数十亿级别的数据段,并实现十微秒级的搜索性能。它为多种编程语言提供了xdb引擎实现。icon-default.png?t=N7T8https://gitcode.com/lionsoul2014/ip2region/overview2:安装依赖(注意这里的版本号,1开头的版本号和我这个版本号有区别,实现代码也是不同的)
<!--ip2region IP地址定位库-->
<dependency>
        <groupId>org.lionsoul</groupId>
        <artifactId>ip2region</artifactId>
        <version>2.6.5</version>
</dependency>

实现步骤:

1:通过HttpServletRequest获取IP地址

/**
 * 在 Nginx 等代理之后获取用户真实 IP 地址
 * @return 用户的真实 IP 地址
 */
public static String getIpAddress(HttpServletRequest request) {
    if (request == null) {
        return null;
    }
    String ip = request.getHeader("x-forwarded-for");
    if (isIpaddress(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
    }
    if (isIpaddress(ip)) {
        ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (isIpaddress(ip)) {
        ip = request.getHeader("HTTP_CLIENT_IP");
    }
    if (isIpaddress(ip)) {
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");
    }
    if (isIpaddress(ip)) {
        ip = request.getRemoteAddr();
        if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
            //根据网卡取本机配置的IP
            try {
                InetAddress inet = InetAddress.getLocalHost();
                ip = inet.getHostAddress();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }
    return ip;
}

2:在服务启动时加载 ip2region.db 到内存中(解决打包 jar 后找不到 ip2region.db 的问题)

@PostConstruct
private static void initIp2regionResource() {
        try {
                InputStream inputStream = new                 ClassPathResource("/ip/ip2region.xdb").getInputStream();
                byte[] dbBinStr = FileCopyUtils.copyToByteArray(inputStream);
                // 创建一个完全基于内存的查询对象(请自行创建静态变量:Searcher searcher )
                searcher = Searcher.newWithBuffer(dbBinStr);
        } catch (Exception e) {
                e.printStackTrace();
        }
}

3:根据ip获取属地

public static String getIpPossessionByFile(String ip,Integer type) {
        if (StringUtils.isNotEmpty(ip)) {
                try {            
                        long sTime = System.nanoTime();
                        String region = searcher.search(ip);
                        long cost = TimeUnit.NANOSECONDS.toMicros(System.nanoTime() - sTime);
                        region = region.replace("|0", "");//去掉特殊字符
                        log.info("{地区: {}, IO操作数: {}, 耗时: {} μs}", region, searcher.getIOCount(), cost);
                        return region;
                } catch (Exception e) {
                        log.error("获取IP地址异常:{} ", e.getMessage());
                        throw new RuntimeException("获取IP地址异常");
                }
        }
        return "未知";
}

注意考虑多并发的情况!!!

  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值