目录
Java中是如何获取IP属地的,主要分为以下几个步
- 通过 HttpServletRequest 对象,获取用户的 IP 地址
- 通过 IP 地址,获取对应的省份、城市
1、HttpServletRequest 获取 Ip
首先写一个 IP 获取的工具类,因为每一次用户的 Request 请求,都会携带上请求的 IP 地址放在请求头中
import org.apache.commons.lang.StringUtils;
import javax.servlet.http.HttpServletRequest;
public class IpAddressUtil {
public static String getIpAddress(HttpServletRequest request) {
String Xip = request.getHeader("X-Real-IP");
String XFor = request.getHeader("X-Forwarded-For");
//多次反向代理后会有多个ip值,第一个ip才是真实ip
if(StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){
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;
}
}
通过此方法,从请求 Header 获取到用户的 IP 地址
2、通过 IP ,获取对应的省份、城市
2.1 Ip2region 介绍
github 地址:https://github.com/lionsoul2014/ip2region
ip2region - 是一个离线IP地址定位库和IP定位数据管理框架,10微秒级别的查询效率,提供了众多主流编程语言的 xdb 数据生成和查询客户端实现。
可以访问 github 或 gitee 地址详细了解
2.1.1 下载 Ip2region xdb 文件
在 github 或 gitee 上拉取代码
打开 Ip2region 文件夹
打开 data 目录后就可以看到 Ip2region.xdb文件了
2.2 Java 代码编写
2.2.1 引入 Maven 依赖
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>2.6.6</version>
</dependency>
2.2.2 示例代码
我们可以预先加载整个 ip2region.xdb 的数据到内存,然后基于这个数据创建查询对象来实现完全基于文件的查询
public class Main {
public static void main(String[] args) {
String path = "xdb 文件的地址";
byte[] buf = new byte[1024];
Searcher searcher = null;
try {
//从 path 加载整个 xdb 到内存中
buf = Searcher.loadContentFromFile(path);
//使用上述 buf 创建一个完全基于内存的查询对象
searcher = Searcher.newWithBuffer(buf);
//查询
String ip = "需要查询的ip地址 1.2.3.4";
//默认的 region 信息都固定了格式:国家|区域|省份|城市|ISP,缺省的地域信息默认是0
String region = searcher.search(ip);
System.out.println(region);
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.2.3 测试结果:
我使用的是阿里云的公网ip