目录
-
背景
-
HttpServletRequest 获取 IP
-
Ip2region
-
Ip2region V2.0 特性
-
ip2region xdb java 查询客户端实现
-
IDEA 中做个测试
背景
细心的朋友应该会发现,最近,继新浪微博之后,头条、腾讯、抖音、知乎、快手、小红书等各大平台陆陆续续都上线了“网络用户 IP 地址显示功能”,境外用户显示的是国家,国内的用户显示的省份,而且此项显示无法关闭,归属地强制显示。
作为技术人,那!这个功能要怎么实现呢?
HttpServletRequest 获取 IP
下面,我就来讲讲,Java 中是如何获取 IP 属地的,主要分为以下几步:
-
通过 HttpServletRequest 对象,获取用户的 「IP」 地址
-
通过 IP 地址,获取对应的省份、城市
首先需要写一个 IP 获取的工具类,因为每一次用户的 Request 请求,都会携带上请求的 IP 地址放到请求头中。
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
/**
* 常用获取客户端信息的工具
*/
public class NetworkUtil {
/**
* 获取ip地址
*/
public static String getIpAddress(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.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
// 本机访问
if ("localhost".equalsIgnoreCase(ip) || "127.0.0.1".equalsIgnoreCase(ip) || "0:0:0:0:0:0:0:1".equalsIgnoreCase(ip)){
// 根据网卡取本机配置的IP
InetAddress inet;
try {
inet = InetAddress.getLocalHost();
ip = inet.getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (null != ip && ip.length() > 15) {
if (ip.indexOf(",") > 15) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}
/**
* 获取mac地址
*/
public static String getMacAddress() throws Exception {
// 取mac地址
byte[] macAddressB