细心的小伙伴可能会发现,最近蘑菇新上线了 IP 属地的功能,小伙伴在发表动态、发表评论以及聊天的时候,都会显示自己的 IP 属地信息
动态显示IP属地
在蘑菇群聊中,也 可 以 展 示 IP 属 地,下面是小伙伴们在交流群中显示的
下面,我就来讲讲,Java 中是如何获取 IP 属地的,主要分为以下几步
-
通过 HttpServletRequest 对象,获 取 用户的 IP 地址
-
通过 IP 地址,获取对应的省份、城市
首先需要写一个 IP 获取的工具类,因为每一次用户的 Request 请 求,都会携带上请求的 IP 地 址放到请求头中。
public class IpUtil {
public static String getIpAddr(ServerHttpRequest request) {
HttpHeaders headers = request.getHeaders();
String ipAddress = headers.getFirst("X-Forwarded-For");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = headers.getFirst("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = headers.getFirst("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddress().getAddress().getHostAddress();
if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
// 根据网卡取本机配置的IP
try {
InetAddress inet = InetAddress.getLocalHost();
ipAddress = inet.getHostAddress();
} catch (UnknownHostException e) {
log.error("根据网卡获取本机配置的IP异常", e);
}
}
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.split(",")[0];
}
return ipAddress;
}
}
这里有三个名词,分别是
-
X-Forwarded-For:一个 HTTP 扩展头部,主要是为了让 Web 服务器获取访问用户的真 实 IP 地址。每个 IP 地址,每个值通过逗号+空格分开,最左边是最原始客户端的 IP 地址,中间如果有多层代理,每⼀层代理会将连接它的客户端 I