GeoLite2—IP地理定位数据库

  |   0 评论   |   0 浏览

GeoLite2—IP地理定位数据库

1.基本介绍

GeoLite2数据库是免费的IP地理定位数据库;

优点:

  • 离线库,不需要网络
  • 数据库丰富
  • 速度快
  • 免费

缺点:

  • 准确度不高,存在偏差
  • 数据更新慢

2.下载 GeoLite2 离线库

image-20220517125947137

官网地址:https://www.maxmind.com/en/home

下载过程稍微有点点麻烦,这里下载了一份最新的,放在网盘,需要测试的可以直接通过这个链接下载:https://www.123pan.com/s/xPY9-J37vH

3.SpringBoot 获取用户的IP

  • 工具类

    public class IpUtils {
        /**
         * 获取用户IP
         * @param request
         * @return
         */
        public static String getIpAddr(HttpServletRequest request) {
    
            String ip = request.getHeader("x-forwarded-for");
    
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("X-Real-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("http_client_ip");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
    
            // 如果是多级代理,那么取第一个ip为客户ip
            if (ip != null && ip.indexOf(",") != -1) {
                ip = ip.substring(ip.lastIndexOf(",") + 1).trim();
            }
            return ip;
        }
    }
    
  • Controller获取HttpServletRequest

    通过上面的工具类,即可获取用户请求的真实IP;

    为了避免重复工作,这里也可以使用AOP解析出用户的IP信息,放到用户的请求对象中

    @RestController
    public class IpController {
        @GetMapping("/user/ip")
        public String userIp(HttpServletRequest request) {
            // 这里就能拿到用户的真实IP
            return IpUtils.getIpAddr(request);
        }
    }
    

4.SpringBoot 整合 GeoLite2

  • 添加依赖

    <dependency>
        <groupId>com.maxmind.geoip2</groupId>
        <artifactId>geoip2</artifactId>
        <version>2.3.0</version>
    </dependency>
    
    <dependency>
        <groupId>com.maxmind.db</groupId>
        <artifactId>maxmind-db</artifactId>
        <version>1.0.0</version>
    </dependency>
    
  • 工具类

    public class GeoIpUtils {
        private static DatabaseReader reader;
    
        private static void init() {
            try {
                // 创建 GeoLite2 数据库 Reader
                // 这里可以放在本地磁盘,也可以随项目放在resource目录下
                File database = new File("F:\\web\\GeoLite2-City.mmdb");
                // 读取数据库内容
                reader = new DatabaseReader.Builder(database).build();
            } catch (Exception ex) {
    
            }
        }
    
        public static void getCityByIP(String ip) throws Exception {
            if (null == reader) {
                init();
            }
    
            InetAddress ipAddress = InetAddress.getByName(ip);
    
            // 获取查询结果
            CityResponse response = reader.city(ipAddress);
    
            // 获取国家信息
            Country country = response.getCountry();
            System.out.println("国家信息:" + JSON.toJSONString(country));
    
            // 获取省份
            Subdivision subdivision = response.getMostSpecificSubdivision();
            System.out.println("省份信息:" + JSON.toJSONString(subdivision));
    
            //城市
            City city = response.getCity();
            System.out.println("城市信息:" + JSON.toJSONString(city));
    
            // 获取城市
            Location location = response.getLocation();
            System.out.println("经纬度信息:" + JSON.toJSONString(location));
        }
    }
    
  • 测试

public static void main(String[] args) throws Exception {
    String ip = "222.**.14.59";
    GeoIpUtils.getCityByIP(ip);
}

输出结果:

国家信息:{"geoNameId":1814991,"isoCode":"CN","name":"China","names":{"de":"China","ru":"Китай","pt-BR":"China","ja":"中国","en":"China","fr":"Chine","zh-CN":"中国","es":"China"}}
省份信息:{"names":{}}
城市信息:{"names":{}}
经纬度信息:{"accuracyRadius":1000,"latitude":34.7732,"longitude":113.722,"timeZone":"Asia/Shanghai"}

5.在线方案

上面一开始介绍GeoLite2时就列举了其离线库更新收录不及时的问题,可能导致一些IP在离线库中并不存在,查找的时候,就会报AddressNotFoundException的错误,如下示例:

图片

遇到这种请求,我们要怎么办呢?

下面就来介绍几种在线IP归属地获取的方式,当本地离线库无法获取的时候,就可以利用三方的在线库,来补充完善;

在线获取的优点:

  • IP更新及时
  • 准确度高

缺点

  • 三方依赖性强
  • 需要付费,免费版本一般都有各种限制

标题:GeoLite2—IP地理定位数据库
作者:llp
地址:https://llinp.cn/articles/2022/05/17/1652764079627.html