首页 文章

如何在servlet中获取客户端的远程地址?

提问于
浏览
63

有什么办法可以让客户端的原始IP地址进入服务器吗?我可以使用 request.getRemoteAddr() ,但我似乎总是得到代理或Web服务器的IP .

我想知道客户端用来连接我的IP地址 . 无论如何我能得到它吗?

9 回答

  • 4

    试试这个:

    public static String getClientIpAddr(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();  
            }  
            return ip;  
        }
    
  • 5

    request.getRemoteAddr() 就是这样 . 您的代理似乎更改了源IP . 当某些代理执行此操作时,他们会在某些自定义http标头中添加原始IP . 使用 request.getHeaderNames()request.getHeaders(name) 并打印所有这些以查看是否没有任何感兴趣的内容 . 就像 X-CLIENT-IP (做了一个,但它们看起来像这样)

  • 1

    我用过的最好的解决方案

    public String getIpAddr(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.getRemoteAddr();      
       }      
       return ip;      
    }
    
  • 4

    你不能以有意义的方式做到这一点 .

    代理可能会也可能不会添加代理头,但在很多情况下,这将是一个内部唯一的地址,所以对你来说没有意义 . 组织边缘的大多数代理都被配置为尽可能少地揭示网络的内部结构 .

    您打算将这些信息用于什么?

  • 10

    由于这通常是部署问题,而不是应用程序问题,另一种方法是适当地配置应用程序容器 . 配置完成后,容器会负责检查相应的 Headers ,并且您的应用程序将继续使用 request.getRemoteAddr() .

    例如,在Tomcat中,您可以使用Remote IP Valve . 我认为大多数应用服务器都具有类似的功能 .

    如果您的前端负载均衡器正在终止SSL连接,并通过HTTP将请求转发到应用服务器,则容器还可以了解情况 . 当您的应用程序需要为自己生成URL时,这很重要 .

  • 0

    如果使用代理或负载均衡器,“x-forwarded-for”请求标头包含原始客户端IP . 但我认为并非所有代理/ lb都添加此标头 .

    这里有一些解析 Headers 的java代码:http://www.codereye.com/2010/01/get-real-ip-from-request-in-java.html

    如果这个 Headers 不存在,那么我会像@Bozho建议的那样继续

  • 0
    String ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null) {
                ipAddress = request.getHeader("X_FORWARDED_FOR");
                if (ipAddress == null){
                    ipAddress = request.getRemoteAddr();
                }
            }
    
  • 101

    为什么不使用这样更优雅的解决方案?

    private static final List<String> IP_HEADERS = Arrays.asList("X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR");
    
    public static String getClientIpAddr(HttpServletRequest request) {
        for (String ipHeader : IP_HEADERS) {
            String ip = request.getHeader(ipHeader);
            if (ip != null && !ip.isEmpty() && !ip.equalsIgnoreCase("unknown")) {
                return ip;
            }
        }
        return request.getRemoteAddr();
    }
    

    重复编码你的代码!

  • -7
    InetAddress inetAddress = InetAddress.getLocalHost();
    String ip = inetAddress.getHostAddress();
    

相关问题