• 【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是否内网(使用正则表达式)


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

  • 相关阅读:
    Linux基础(Ubuntu16.04):安装vim及配置
    Ubuntu16.04 安装ROS及其IDE
    python格式转换的记录
    python爬虫selenium相关
    【LAMP】搭建Web网站过程中的记录【Ubuntu18.04+Apache2.4+PHP7.2+MySQL5.7】
    【疯狂挖坑】linux服务器尝试中的问题(nohup等)
    逻辑回归与全连接神经网络联系的简单理解记录
    Unity3d开发中遇到的问题记录
    python中numpy库的一些使用
    Deep Learning论文翻译(Nature Deep Review)
  • 原文地址:https://www.cnblogs.com/hyhy904/p/11167520.html
Copyright © 2020-2023  润新知