首先在实时程序中 调用接口不现实,肯定是调用离线库去解决地址的,这种准确性很重要,现在推荐下面这个离线库:
注意点:
1)下载包 放到对应的目录,特别是在生产环境,一般放在lib目录下 动态写活
https://dev.maxmind.com/geoip/geoip2/geolite2/#Downloads
下载解压
2)写代码:
代码: 执行main方法
package test_demo;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.InetAddress;
public class IPUtils {
private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
/**
* 全局静态变量,DatabaseReader,保证类加载时加载一次
*/
private static DatabaseReader reader;
/**
* 静态代码块,保证项目启动只获取一次文件
*/
static {
File database = null;
try {
//绝对路径读取文件方式
database = new File("C:\\Users\\Administrator\\Desktop\\部署flume+storm文档\\Flume优化\\GeoLite2-City_20191126\\GeoLite2-City.mmdb");
// 通过 InputStream 流式读取文件,目的解决无法通过File方式读取jar包内的文件的问题·1
// database = getFile("GeoLite2-City.mmdb", "geolite2.mmdb");
logger.info("-------加载文件");
reader = new DatabaseReader.Builder(database).build();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 解析IP
*
* @param ip
* @return
*/
public static IPEntity getIPMsg(String ip) {
IPEntity msg = new IPEntity();
try {
InetAddress ipAddress = InetAddress.getByName(ip);
CityResponse response = reader.city(ipAddress);
Country country = response.getCountry();
Subdivision subdivision = response.getMostSpecificSubdivision();
City city = response.getCity();
Postal postal = response.getPostal();
Location location = response.getLocation();
msg.setCountryName(country.getNames().get("zh-CN"));
msg.setCountryCode(country.getIsoCode());
msg.setProvinceName(subdivision.getNames().get("zh-CN"));
msg.setProvinceCode(subdivision.getIsoCode());
msg.setCityName(city.getNames().get("zh-CN"));
msg.setPostalCode(postal.getCode());
//经度
msg.setLongitude(location.getLongitude());
//纬度
msg.setLatitude(location.getLatitude());
} catch (IOException e) {
e.printStackTrace();
} catch (GeoIp2Exception e) {
e.printStackTrace();
}
return msg;
}
/**
* 读取classpath下的文件
*
* @param fileName 原文件全名
* @param newFileName 缓存的新文件的名称
* @return
* @throws IOException
*/
public static File getFile(String fileName, String newFileName) throws IOException {
//读取 ClassPath 路径下指定资源的输入流
// ClassPathResource resource = new ClassPathResource(fileName);
// InputStream inputStream = resource.getInputStream();
InputStream inputStream = IPUtils.class.getResourceAsStream(fileName);
File file = new File(newFileName);
inputstreamToFile(inputStream, file);
return file;
}
/**
* InputStream -> File
*
* @param inputStream
* @param file
*/
private static void inputstreamToFile(InputStream inputStream, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// IPEntity msg = IPUtils.getIPMsg("128.101.101.101");
IPEntity msg = IPUtils.getIPMsg("119.123.225.83");
// IPEntity msg = IPUtils.getIPMsg("180.118.240.225");
System.out.println(msg.toString());
}
}
对应的实体类 :
package test_demo; public class IPEntity { //国家 String countryName; //国家代码 String countryCode; //省份 String provinceName; String provinceCode; public IPEntity() { } public String getCountryName() { return countryName; } public void setCountryName(String countryName) { this.countryName = countryName; } public String getCountryCode() { return countryCode; } public void setCountryCode(String countryCode) { this.countryCode = countryCode; } public String getProvinceName() { return provinceName; } public void setProvinceName(String provinceName) { this.provinceName = provinceName; } public String getProvinceCode() { return provinceCode; } public void setProvinceCode(String provinceCode) { this.provinceCode = provinceCode; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getPostalCode() { return postalCode; } public void setPostalCode(String postalCode) { this.postalCode = postalCode; } public Double getLongitude() { return longitude; } public void setLongitude(Double longitude) { this.longitude = longitude; } public Double getLatitude() { return latitude; } public void setLatitude(Double latitude) { this.latitude = latitude; } //城市名称 String cityName; //邮政编码 String postalCode; //经度 Double longitude; //纬度 Double latitude; @Override public String toString() { return "IPEntity{" + "countryName='" + countryName + '\'' + ", countryCode='" + countryCode + '\'' + ", provinceName='" + provinceName + '\'' + ", provinceCode='" + provinceCode + '\'' + ", cityName='" + cityName + '\'' + ", postalCode='" + postalCode + '\'' + ", longitude=" + longitude + ", latitude=" + latitude + '}'; } }