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.geoip2groupId>
            <artifactId>geoip2artifactId>
            <version>2.8.1version>
 dependency>

第三、下载geoip2的库文件,并解压
下载库文件
java通过ip地址获取相应对应的城市_第1张图片
解压后的文件
java通过ip地址获取相应对应的城市_第2张图片

第四、上代码

    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内

你可能感兴趣的:(java)