【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是否內網(使用正則表達式)


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM