1、下载离线数据库
1.1、下载
1.1.1、方式一、官网
https://dev.maxmind.com/geoip/geolite2-free-geolocation-data
注册–>下载
Sign Up for GeoLite2–>Download Files
https://www.maxmind.com/en/accounts/886739/geoip/downloads
下载页面分几种类型数据,可以按照需求选择,国家级、城市级
1.1.1、方式二、百度云
城市级,可以解析到具体的国家、省份、城市
链接:https://pan.baidu.com/s/1IcIRW_tPRaa-VwrrH8FIBg?pwd=5xox
提取码:5xox
国家级,只能解析到具体的国家
链接:https://pan.baidu.com/s/1ZGEA2BMq8K0OQm4zJWeISg?pwd=udgy
提取码:udgy
2、SpringBoot集成
2.1、maven
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>2.16.1</version>
</dependency>
2.2 代码
yml
static:
databaseUrl: F:/java/ynWord/jeecg-boot/static/ipDataBase/GeoLite2-City.mmdb
properties
@Data
@Component
@ConfigurationProperties(prefix = "static")
public class StaticTemplateProperties {
private String databaseUrl;
}
实体
@Data
public class IpInfo {
public IpInfo(String ip, String ipAddress) {
this.ip = ip;
this.ipAddress = ipAddress;
}
private String ip;
private String ipAddress;
private String provinceName;
private String cityName;
}
bean
@Slf4j
@Configuration
public class IpDataBases {
@Resource
private StaticTemplateProperties templateProperties;
@Bean
public DatabaseReader databaseReader() {
FileInputStream database = null;
try {
// 创建数据库
database = new FileInputStream(new File(templateProperties.getDatabaseUrl()));
return new DatabaseReader.Builder(database).build();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
运用代码
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.City;
import com.maxmind.geoip2.record.Location;
import com.maxmind.geoip2.record.Postal;
import com.maxmind.geoip2.record.Subdivision;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class IpAddressUtil {
@Resource
private StaticTemplateProperties templateProperties;
@Resource
private DatabaseReader databaseReader;
public IpInfo getIpInfo( ) {
HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
String ip = getIpAddress(request);
if (StringUtils.isEmpty(ip)) {
return null;
}
return parseIp(ip);
}
public IpInfo getIpInfo(HttpServletRequest request) {
String ip = getIpAddress(request);
if (StringUtils.isEmpty(ip)) {
return null;
}
return parseIp(ip);
}
public IpInfo parseIp(String ip) {
log.info("当前IP:{}", ip);
IpInfo ipInfo = new IpInfo(ip, "未知");
try {
// FileInputStream database = new FileInputStream(new File(templateProperties.getDatabaseUrl()));
// // 创建数据库
// DatabaseReader reader = new DatabaseReader.Builder(database).build();
// 获取 IP 地址信息
InetAddress ipAddress = InetAddress.getByName(ip);
// 获取查询信息
CityResponse response = databaseReader.city(ipAddress);
// 国家信息
// Country country = response.getCountry();
// log.debug(country.getIsoCode()); // 'CN'
// log.debug(country.getName()); // 'China'
// // {de=China, ru=Китай, pt-BR=China, ja=中国, en=China, fr=Chine, zh-CN=中国, es=China}
// log.debug(country.getNames());
// log.debug(country.getNames().get("zh-CN")); // '中国'
// 省级信息
Subdivision subdivision = response.getMostSpecificSubdivision();
// {{en=Shanghai, fr=Municipalité de Shanghai, zh-CN=上海, pt-BR=Xangai}}
log.debug("省份-信息:{}", subdivision.getNames());
log.debug("省份(编码):{}", subdivision.getIsoCode()); // 'SH'
log.debug("省份(英文):{}", subdivision.getName()); // 'Shanghai'
log.debug("省份(中文):{}", subdivision.getNames().get("zh-CN")); // '上海'
ipInfo.setProvinceName(subdivision.getNames().get("zh-CN"));
if (StringUtils.isNotEmpty(ipInfo.getProvinceName())) {
ipInfo.setIpAddress(ipInfo.getProvinceName());
}
// 城市信息
City city = response.getCity();
log.debug("城市(英文):{}", city.getName()); // 'Shanghai'
log.debug("城市(中文):{}", city.getNames().get("zh-CN")); // '上海'
ipInfo.setCityName(city.getNames().get("zh-CN"));
if (StringUtils.isNotEmpty(ipInfo.getCityName())) {
ipInfo.setIpAddress(ipInfo.getProvinceName() + "-" + ipInfo.getCityName());
}
// 邮政编码(国内的可能获取不到)
Postal postal = response.getPostal();
log.debug(postal.getCode()); // '55423'
// 经纬度
Location location = response.getLocation();
log.debug("维度:{}", location.getLatitude()); // 纬度 31.2222
log.debug("经度:{}", location.getLongitude()); // 经度 121.4581
} catch (Exception e) {
e.printStackTrace();
}
return ipInfo;
}
/**
* 获取Ip地址
*
* @param request
* @return
*/
public static String getIpAddress(HttpServletRequest request) {
String Xip = request.getHeader("X-Real-IP");
String XFor = request.getHeader("X-Forwarded-For");
if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
//多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = XFor.indexOf(",");
if (index != -1) {
return XFor.substring(0, index);
} else {
return XFor;
}
}
XFor = Xip;
if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
return XFor;
}
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getRemoteAddr();
}
return XFor;
}
}