通过 HttpServletRequest 获取客户端 IP 地址


在 Java Web 应用中,想要在接口中获取到发送请求的客户端 IP 地址,需要依赖请求对象 —— HttpServletRequest。

那么,首先就是要先获取到请求的对象。

在 Spring Boot 中,只需在接口方法上加上 HttpServletRequest 或 HttpServletResponse 参数,Spring Boot 就会自动绑定这两个对象,然后可以直接使用。如果你的方法有其他参数,只需把这两个加到后面即可。例如:

@GetMapping("/getSomething")
public String getSomething(..., HttpServletRequest request, HttpServletResponse response) {
    //...
}

这是最常用的一种方法,当然除了这种方式,在 Spring Boot 中还可以使用注解 @Autowired 注入或通过 RequestContextHolder 来获取请求对象,这里就不展开叙述了。

在得到请求对象 HttpServletRequest 对象后,一般的,我们可以使用 request.getRemoteAddr() 来获取到客户端对应的 IP 地址。

但是,如果使用了 Nginx 等反向代理软件,则不能只简单地通过上述代码来获取 IP;并且,如果使用了多级反向代理的话,那么在获取 X-Forwarded-For 的值时,得到的应是一串 IP 地址,此种情况下,X-Forwarded-For 中第一个非 unknown 的有效 IP 字符串,则为真实 IP 地址。

Talk is cheap, show me code.

下面是一个封装的工具类,用于从 HttpServletRequest 对象中获取相应的客户端 IP 地址。

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class IpUtil {
    private static final String UNKNOWN = "unknown";
    private static final String LOCALHOST_IP = "127.0.0.1";
    // 客户端与服务器同为一台机器,获取的 ip 有时候是 ipv6 格式
    private static final String LOCALHOST_IPV6 = "0:0:0:0:0:0:0:1";
    private static final String SEPARATOR = ",";

    // 根据 HttpServletRequest 获取 IP
    public static String getIpAddress(HttpServletRequest request) {
        if (request == null) {
            return "unknown";
        }
        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("X-Forwarded-For");
        }
        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("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if (LOCALHOST_IP.equalsIgnoreCase(ip) || LOCALHOST_IPV6.equalsIgnoreCase(ip)) {
                // 根据网卡取本机配置的 IP
                InetAddress iNet = null;
                try {
                    iNet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                if (iNet != null)
                    ip = iNet.getHostAddress();
            }
        }
        // 对于通过多个代理的情况,分割出第一个 IP
        if (ip != null && ip.length() > 15) {
            if (ip.indexOf(SEPARATOR) > 0) {
                ip = ip.substring(0, ip.indexOf(SEPARATOR));
            }
        }
        return LOCALHOST_IPV6.equals(ip) ? LOCALHOST_IP : ip;
    }
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM