细心的小伙伴可能会发现,最近蘑菇新上线了 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 地址,每个值通过逗号+空格分开,最左边是最原始客户端的