在Java中获取客户端IP地址
在Java Web应用中获取客户端IP地址是一个常见需求,但需要注意一些细节,因为客户端可能通过代理服务器访问,以下是几种获取IP的方法:

(图片来源网络,侵删)
基本方法(直接获取)
String ipAddress = request.getRemoteAddr();
这种方法在客户端直接连接服务器时有效,但如果客户端通过代理服务器访问,获取到的将是代理服务器的IP。
考虑代理服务器的情况
当客户端通过代理服务器(如Nginx、Apache等)访问时,真实的IP地址可能存储在HTTP头中,常见的头字段有:
X-Forwarded-ForProxy-Client-IPWL-Proxy-Client-IPHTTP_CLIENT_IPHTTP_X_FORWARDED_FOR
推荐的完整获取方法
public 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();
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ip != null && ip.contains(",")) {
ip = ip.split(",")[0].trim();
}
return ip;
}
Spring Boot中的简化方法
如果你使用的是Spring Boot,可以注入HttpServletRequest并使用上述方法:
@RestController
public class IpController {
@Autowired
private HttpServletRequest request;
@GetMapping("/ip")
public String getIp() {
return getIpAddress(request);
}
// 上面的getIpAddress方法实现...
}
注意事项
-
安全性:
X-Forwarded-For等头字段可以被客户端伪造,不要完全信任这些值,在需要高安全性的场景下,应该进行验证。
(图片来源网络,侵删) -
反向代理:如果你的应用部署在反向代理后面,确保代理服务器正确设置了这些头字段。
-
IPv6:上述代码也适用于IPv6地址。
-
本地测试:在本地开发时,
getRemoteAddr()通常返回0.0.1或0:0:0:0:0:0:0:1。 -
负载均衡:在负载均衡环境下,可能需要考虑
X-Forwarded-For链中的多个IP。
(图片来源网络,侵删)
使用第三方库
如果你不想自己实现,可以使用一些第三方库如spring-boot-starter-actuator提供的端点,或者使用专门的IP工具库。
希望这些方法能帮助你在Java应用中正确获取客户端IP地址!
