SpringBoot获取Ip并解析地址,Docker部署 (ip2region.xdb)
踩坑:1.Docker读取resources路径错误,更改读取文件方式,使用InputStream读取就不会出现找不到文件的情况
2.Maven打包项目时没有把ip2region.xdb打进jar包,导致无法读取出现ArrayIndexOutOfBoundsException(配置pom.xml
**/*.xdb)
3.ip2region.xdb自行官网下载,这里无法上传文件
流程
1. 引入依赖
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>2.7.0</version>
</dependency>
2.获取IP工具类
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
@Slf4j
public class IPUtils {
/**
* 获取IP地址
*
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = null;
try {
ip = request.getHeader("x-forwarded-for");
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StrUtil.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} catch (Exception e) {
log.error("IPUtils ERROR:",e);
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if(!StrUtil.isEmpty(ip) && ip.length() > 15) {
if(ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}
}
3.解析IP地址工具类
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;
import java.io.IOException;
import java.io.InputStream;
@Slf4j
public class getCityInfoUtil {
private static Searcher searcher;
/**
* 获取城市信息(从ip2region.db中获取地理位置)
*/
public static String getCityInfo(String ip) {
if (searcher == null) {
// 处理未初始化 searcher 对象的情况
return null;
}
try {
return searcher.search(ip);
} catch (Exception e) {
log.error("failed to search({})", ip, e);
}
// 3、关闭资源
try {
searcher.close();
} catch (IOException e) {
System.out.printf("failed to search(%s): %s\n", e);
}
return null;
}
static {
try {
InputStream inputStream = new ClassPathResource("/ip2region.xdb").getInputStream();
byte[] dbBinStr = FileCopyUtils.copyToByteArray(inputStream);
// 创建一个完全基于内存的查询对象
searcher = Searcher.newWithBuffer(dbBinStr);
} catch (Exception e) {
log.error("failed to create content cached searcher", e);
}
}
public static void main(String[] args) {
System.out.println(getCityInfo("8.8.8.8"));
}
}