java通過ip地址獲取相應對應的城市

發現了一比較好的本地ip對應地址的庫資源文件--做一下筆記。
官方網站 https://dev.maxmind.com/geoip/geoip2/geolite2/
這裏提供了免費的庫文件,還有很好的api支持。
(國內也用一個叫www.ipip.net 也有類似的)

第一、java 獲取IP地址

    public static String getRemortIP(HttpServletRequest request) {

        String ip = request.getHeader("x-forwarded-for");
        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.getRemoteAddr();
        }
        if (ip.contains(",")) {
            ip = ip.split(",")[0];
        }
        return ip;
    }

第二、使用geoip2先引入他的jar

 <dependency>
            <groupId>com.maxmind.geoip2</groupId>
            <artifactId>geoip2</artifactId>
            <version>2.8.1</version>
 </dependency>

第三、下載geoip2的庫文件,並解壓
下載庫文件
下載庫文件
解壓後的文件
解壓後的文件

第四、上代碼

    public static void main(String[] args) {
        try {
            // 創建 GeoLite2 數據庫     
            File database = new File("C:\\Users\\Administrator\\Desktop\\GeoLite2-City_20180306\\GeoLite2-City.mmdb");     
            // 讀取數據庫內容   
            DatabaseReader reader = new DatabaseReader.Builder(database).build();       
            InetAddress ipAddress = InetAddress.getByName("43.243.12.185");     
            // 獲取查詢結果      
            CityResponse response = reader.city(ipAddress); 
            System.out.println(JSONObject.fromObject(response));
             // 獲取國家信息
              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()); 
              Postal postal = response.getPostal();
              System.out.println(postal.getCode()); 
              System.out.println(city.getNames().get("zh-CN")); 
              //獲取座標
              Location location = response.getLocation();
              System.out.println(location.getLatitude());  
              System.out.println(location.getLongitude()); 

        } catch (Exception e) {
            // TODO: handle exception
        }

    }

第五、如果想在項目中使用可以將他封裝成一個工具類

import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.concurrent.locks.ReentrantLock;

import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.City;
import com.maxmind.geoip2.record.Country;
import com.maxmind.geoip2.record.Subdivision;

public class IpAddress {

    private static DatabaseReader reader;
    private static ReentrantLock lock = new ReentrantLock();

    static {
        load();
    }

    public static String findOne(String ip) {
        String[] ipAddrs = find(ip);
        if (ipAddrs != null && ipAddrs.length > 0) {
            StringBuilder addrBuilder = new StringBuilder();
            for (String addr : ipAddrs) {
                addrBuilder.append(addr);
            }
            return addrBuilder.toString();
        }
        return null;
    }

    public static String[] find(String ip) {
        try {
            String addr[] = new String[3];
            InetAddress ipAddress = InetAddress.getByName(ip);
            // 獲取查詢結果
            CityResponse response = reader.city(ipAddress);
            // 獲取國家名稱
            Country country = response.getCountry();
            addr[0] = country.getNames().get("zh-CN");
            // 獲取省分名稱
            Subdivision subdivision = response.getMostSpecificSubdivision();
            addr[1] = subdivision.getNames().get("zh-CN");
            // 獲取城市名稱
            City city = response.getCity();
            addr[2] = city.getNames().get("zh-CN");
            return addr;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void load() {
        lock.lock();
        // 創建 GeoLite2 數據庫
        InputStream database = IpAddress.class
                .getResourceAsStream("/files/GeoLite2-City.mmdb");
        // 讀取數據庫內容
        try {
            reader = new DatabaseReader.Builder(database).build();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            try {
                if (null != database) {
                    database.close();
                }
            } catch (IOException e) {
            }
        }
    }

    public static void main(String args[]) {
        Long st = System.nanoTime();
        System.out.println(Arrays.toString(IpAddress.find("43.243.12.185")));
        System.out.println(IpAddress.findOne("111.23.106.179"));
        System.out.println(IpAddress.findOne("182.131.12.12"));
        Long et = System.nanoTime();
        System.out.println((et - st));
    }
}

使用新能還是相當高的,一個查詢基本是1ms內

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章