离线IP归属地查询
项目已经使用的是纯真的IP离线库,客户反馈经常不准,尝试寻找更好的替代方案,尝试了geoLite2的库,结果发现也不准,于是放弃了升级改造。通过https://www.ipip.net/ 查询对比得知,因为更新的时间较新的原因,付费的geo库准确。尝试的流程如下:
第一步:新建springboot工程,添加以下依赖
<!-- geo ip2 实现离线IP 查询 -->
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>2.13.1</version>
</dependency>
第二步:下载离线IP库
地址:https://dev.maxmind.com/geoip/geoip2/geolite2/
现在需要注册用户,登录才能下载,最新的免费版的离线库
第三步:写测试代码
package com.example.demo.geoLite2;
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.*;
import org.springframework.boot.CommandLineRunner;
import java.io.File;
import java.net.InetAddress;
public class GeoLiteIP implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
}
/**
* 调用ASN
* 这个是获取自治系统编号的
* @param ip
* @throws Exception
*/
public static void getIpAsn(String ip) throws Exception {
//GeoIP2数据库文件
File database = new File("F:\\geoLite2\\GeoLite2-ASN_20200519\\GeoLite2-ASN.mmdb");
// 创建 DatabaseReader对象
DatabaseReader reader = new DatabaseReader.Builder(database).build();
InetAddress ipAddress = InetAddress.getByName(ip);
AsnResponse response = reader.asn(ipAddress);
response.getClass().getMethod("").invoke(response);
System.out.println(response.getAutonomousSystemOrganization());//运营商
System.out.println(response.getAutonomousSystemNumber());//运营商的编号
}
/**
* 调用Country
* 这个是获取Country级别的,数据库文件小很多,如果只需要查国家可以用
* @param ip
* @throws Exception
*/
public static void getIpCountry(String ip) throws Exception {
//GeoIP2数据库文件
File database = new File("F:\\geoLite2\\GeoLite2-Country_20200519\\GeoLite2-Country.mmdb");
// 创建 DatabaseReader对象
DatabaseReader reader = new DatabaseReader.Builder(database).build();
InetAddress ipAddress = InetAddress.getByName(ip);
CountryResponse response = reader.country(ipAddress);
Country country = response.getCountry();
System.out.println(country.getIsoCode());//国家编码
System.out.println(country.getName());//国家名称-英文
System.out.println(country.getNames().get("zh-CN"));//国家名称-中文
}
/**
* 调用City
* 这个是获取City级别的,也包含了获取国家的
* @param ip
* @throws Exception
*/
public static void getIpCity(String ip) throws Exception {
//GeoIP2数据库文件
File database = new File("F:\\geoLite2\\GeoLite2-City_20200519\\GeoLite2-City.mmdb");
// 创建 DatabaseReader对象
DatabaseReader reader = new DatabaseReader.Builder(database).build();
InetAddress ipAddress = InetAddress.getByName(ip);
CityResponse response = reader.city(ipAddress);
Country country = response.getCountry();
System.out.println(country.getIsoCode());
System.out.println(country.getName());
System.out.println(country.getNames().get("zh-CN"));
Subdivision subdivision = response.getMostSpecificSubdivision();
System.out.println(subdivision.getName());//省名
System.out.println(subdivision.getIsoCode());//省编码
System.out.println(subdivision.getNames().get("zh-CN"));//省名称-中文
City city = response.getCity();
System.out.println(city.getName());//城市名称-英文
System.out.println(city.getNames().get("zh-CN"));//城市名称-中文
Postal postal = response.getPostal();
System.out.println(postal.getCode());//邮编
Location location = response.getLocation();
System.out.println(location.getLatitude());//纬度
System.out.println(location.getLongitude());//经度
}
public static void main(String[] args) {
try {
getIpAsn("112.53.148.62");
getIpCountry("112.53.148.62");
getIpCity("112.53.148.62");
//城市定位不准,纯真定位在四川,geo定位在杭州,实际在无锡,放弃替换纯真的
} catch (Exception e) {
e.printStackTrace();
}
}
}
最后还是懒人方法,不变应万变!!