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内

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值