一、终极解决方案(两步搞定)
第一步:修改 Nginx 配置(最关键)
打开你的 Nginx 配置文件,在 location / 里必须加这三行:
nginx
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
完整示例:
nginx
location / {
proxy_pass http://127.0.0.1:18016;
proxy_set_header X-Real-IP $remote_addr; # 真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
改完重启 Nginx!
bash
运行
nginx -s reload
第二步:使用我优化后的真实 IP 工具类(直接替换你的)
java
运行
package com.qc.web.hzxhq.controller;
import javax.servlet.http.HttpServletRequest;
public class IpUtils {
private static final String UNKNOWN = "unknown";
private static final String LOCAL_IP = "127.0.0.1";
/**
* 获取用户【真正的客户端IPv4】(经过Nginx也能拿到)
*/
public static String getRealIpv4(HttpServletRequest request) {
// 优先从 Nginx 传递的请求头获取
String ip = request.getHeader("X-Real-IP");
// 多级代理
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
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.getRemoteAddr();
}
// 处理多级代理:取第一个IP(真实客户端)
if (ip != null && ip.contains(",")) {
ip = ip.split(",")[0].trim();
}
// 本地访问
if ("0:0:0:0:0:0:0:1".equals(ip)) {
ip = LOCAL_IP;
}
return ip;
}
}
二、为什么你之前拿到的是 Nginx 地址?
因为 没配置 Nginx 传递真实 IP,所以 Java 只能看到代理服务器的 IP。
配置后:
X-Real-IP= 用户真实 IPX-Forwarded-For= 用户 IP, 代理 1, 代理 2...
三、使用方式(你的 Controller 里这样调用)
java
运行
@GetMapping("/testIp")
public void testIp(HttpServletRequest request) {
String realIp = IpUtils.getRealIpv4(request);
System.out.println("用户真实IPv4 = " + realIp);
}