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

时间:2011-01-13 10:06:12

标签: servlets proxy client ip-address

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

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

11 个答案:

答案 0 :(得分:101)

试试这个:

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;  
    }  

答案 1 :(得分:10)

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

答案 2 :(得分:5)

我用过的最好的解决方案

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;      
} 

答案 3 :(得分:4)

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

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

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

答案 4 :(得分:4)

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

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

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

答案 5 :(得分:1)

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

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

如果此标题不存在,那么我将继续@Bozho建议

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

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();
}

删除重复代码!

答案 8 :(得分:0)

为什么我认为我们应该首先尝试从标头'<input type="file" class="form-control" name="gallery_image[]"> '获取IP?如果您来自X-Forwarded-For,则可能是client's real ip or last proxy's ip which forwards the request。因此,我们无法确定它属于哪个条件。但是,如果将'X-Forwarded-For'设置为标头,则客户端ip必定是从其获得的内容的最左侧部分。

request.getRemoteAddr()

答案 9 :(得分:0)

request.getHeader("True-Client-IP")

它将返回客户端IP地址

答案 10 :(得分:-7)

InetAddress inetAddress = InetAddress.getLocalHost();
String ip = inetAddress.getHostAddress();