在java中实现获取客户端IP地址

在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。

如果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为 http://www.123.com.cn 的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。

以下是具体代码实现

/**
 * 获取ip地址
 *
 * 需要在nginx中配置:(否则,获取的是nginx服务器的ip地址)
 *      proxy_set_header X-real-ip $remote_addr;
 *      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 */
public class IpUtils {
          
   

    /**
     * 在服务中获取用户的ip地址
     * @param request
     * @return
     */
    public static String getIpAddressAtService(HttpServletRequest request) {
          
   
        String ipAddress = null;
        try {
          
   
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
          
   
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
          
   
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
          
   
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
          
   
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
          
   
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
          
   
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照,分割
            if (ipAddress != null && ipAddress.length() > 15) {
          
    // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
          
   
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
          
   
            ipAddress="";
        }
        // ipAddress = this.getRequest().getRemoteAddr();

        return ipAddress;
    }

    /**
     * 在网关中获取用户的ip地址
     * @param request
     * @return
     */
    public static String getIpAddressAtGateway(ServerHttpRequest request) {
          
   
        HttpHeaders headers = request.getHeaders();
        String ip = headers.getFirst("x-forwarded-for");
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
          
   
            // 多次反向代理后会有多个ip值,第一个ip才是真实ip
            if (ip.indexOf(",") != -1) {
          
   
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
   
            ip = headers.getFirst("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
   
            ip = headers.getFirst("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
   
            ip = headers.getFirst("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
   
            ip = headers.getFirst("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
   
            ip = headers.getFirst("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
   
            ip = request.getRemoteAddress().getAddress().getHostAddress();
        }
        return ip;
    }
}
经验分享 程序员 微信小程序 职场和发展