zoukankan      html  css  js  c++  java
  • 【Java】通过ip地址获取详细地域信息(不通过API使用本地库)

    MaxMind GeoIP2

    服务能识别互联网用户的地点位置与其他特征,应用广泛,包括个性化定制内容、诈欺检测、广告定向、网站流量分析、执行规定、地理目标定位、地理围栏定位 (geo-fencing)以及数字版权管理。目前使用 GeoIP 更多是配合Nginx或Apache服务器进行日志分析获取网站访问量地域分布状况。

    GeoIP 分为商业版和免费版,免费版比商业版精度差了许多,经测试对于城市定位确实有差距,能否接受看你的精度要求!(老板说免费的可以了,哈哈)

    下载GeoIP2的库,这个库是经常更新的,如果数据要求很高的,需要经常更新(我们不高,预计一年一次)

    官网下载地址https://dev.maxmind.com/geoip/geoip2/geolite2/ 

    但是好像网站不太稳定,我这边3个都下载好了,可【点击下载】

    关于Java如何使用

    不用担心,已经有开源库,maven下载一个

    <dependency>
    <groupId>com.maxmind.geoip2</groupId>
    <artifactId>geoip2</artifactId>
    <version>2.12.0</version>
    </dependency>
    没有maven,怎么办?不怕,我上传了,可【点击下载】

    使用用到的工具类

    import com.maxmind.geoip2.DatabaseReader;
    import com.maxmind.geoip2.model.AsnResponse;
    import com.maxmind.geoip2.model.CityResponse;
    import com.maxmind.geoip2.model.CountryResponse;
    import com.maxmind.geoip2.record.City;
    import com.maxmind.geoip2.record.Country;
    import com.maxmind.geoip2.record.Location;
    import com.maxmind.geoip2.record.Postal;
    import com.maxmind.geoip2.record.Subdivision;
     

    调用ASN

    这个是获取自治系统编号的

    public static void testAsn(String testIp) throws Exception {
    //GeoIP2数据库文件,把数据库文件直接放d盘下(可以随意喜欢的位置)
    File database = new File("D:/GeoLite2-ASN.mmdb");

    // 创建 DatabaseReader对象
    DatabaseReader reader = new DatabaseReader.Builder(database).build();

    InetAddress ipAddress = InetAddress.getByName(testIp);

    AsnResponse response = reader.asn(ipAddress);

    System.out.println(response.getAutonomousSystemOrganization());
    System.out.println(response.getAutonomousSystemNumber());

    }
     

    调用Country

    这个是获取Country级别的,数据库文件小很多,速度可以优化很多

    public static void testCity(String testIp) throws Exception {
    //GeoIP2数据库文件,把数据库文件直接放d盘下(可以随意喜欢的位置)
    File database = new File("D:/test/ip/GeoLite2-City.mmdb");

    // 创建 DatabaseReader对象
    DatabaseReader reader = new DatabaseReader.Builder(database).build();

    InetAddress ipAddress = InetAddress.getByName(testIp);

    CityResponse response = reader.city(ipAddress);

    Country country = response.getCountry();
    System.out.println(country.getIsoCode()); // 'US'
    System.out.println(country.getName()); // 'United States'
    System.out.println(country.getNames().get("zh-CN")); // '美国'

    Subdivision subdivision = response.getMostSpecificSubdivision();
    System.out.println(subdivision.getName()); // 'Minnesota'
    System.out.println(subdivision.getIsoCode()); // 'MN'
    System.out.println(subdivision.getNames().get("zh-CN"));

    City city = response.getCity();
    System.out.println(city.getName()); // 'Minneapolis'
    System.out.println(city.getNames().get("zh-CN"));

    Postal postal = response.getPostal();
    System.out.println(postal.getCode()); // '55455'

    Location location = response.getLocation();
    System.out.println(location.getLatitude()); // 44.9733
    System.out.println(location.getLongitude()); // -93.2323
    }
    调用City

    这个是获取City级别的,文件相对比较大,看情况使用(不用担心,我们就是这样用的,速度还行暂时)

    public static void testCity(String testIp) throws Exception {
    //GeoIP2-City 数据库文件,把数据库文件直接放d盘下(可以随意喜欢的位置)
    File database = new File("D:/test/ip/GeoLite2-City.mmdb");

    // 创建 DatabaseReader对象
    DatabaseReader reader = new DatabaseReader.Builder(database).build();

    InetAddress ipAddress = InetAddress.getByName(testIp);

    CityResponse response = reader.city(ipAddress);

    Country country = response.getCountry();
    System.out.println(country.getIsoCode()); // 'US'
    System.out.println(country.getName()); // 'United States'
    System.out.println(country.getNames().get("zh-CN")); // '美国'

    Subdivision subdivision = response.getMostSpecificSubdivision();
    System.out.println(subdivision.getName()); // 'Minnesota'
    System.out.println(subdivision.getIsoCode()); // 'MN'
    System.out.println(subdivision.getNames().get("zh-CN"));

    City city = response.getCity(http://www.my516.com);
    System.out.println(city.getName()); // 'Minneapolis'
    System.out.println(city.getNames().get("zh-CN"));

    Postal postal = response.getPostal();
    System.out.println(postal.getCode()); // '55455'

    Location location = response.getLocation();
    System.out.println(location.getLatitude()); // 44.9733
    System.out.println(location.getLongitude()); // -93.2323
    }
     

    测试模块

    public static void main(String[] args) throws Exception {

    String testIp="128.101.101.101";

    //测试Asn
    testAsn(testIp);

    //测试国家
    testCountry(testIp);

    //测试城市
    testCity(testIp);

    }
     

    Ps:如果ip是内网怎么办?不用担心,一定会报错,因为根本不可能找到数据,哈哈

    解决方法:把ip先放进去判断是否是内网先再查询,这里我是使用正则表达式,之前发过了,请看【Java】判断IP是否内网(使用正则表达式)


    ---------------------

  • 相关阅读:
    P1265 公路修建 最小生成树
    P1991 无线通讯网 最小生成树
    Stock Chase 拓扑
    Rank of Tetris 拓扑排序+并查集
    P1169 [ZJOI2007]棋盘制作 DP悬线法
    P4147 玉蟾宫 二维DP 悬线法
    P1341 无序字母对 欧拉回路
    P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 记忆化搜索dfs
    BSTestRunner插件的用法.py
    Selenium
  • 原文地址:https://www.cnblogs.com/hyhy904/p/11167520.html
Copyright © 2011-2022 走看看