2013-08-21 111 views
18

我發現一些不同的方式來在servlet中獲取IP。但我不知道哪一個是對的,爲什麼。什麼是正確的方式來獲取請求的IP

1:

request.getHeader("X-Real-IP") 

2:

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

3:

String ip=request.getHeader("x-forwarded-for"); 
       if(ip==null){ 
        ip=request.getRemoteAddr(); 
       } 
       String ips[]=ip.split(",");` 
           ip=ips[0]; 
+0

檢查此鏈接:http://stackoverflow.com/questions/10363069/how-can-i-retrieve-ip-address-from-http-header-in-java/10363109#10363109 – 2013-08-21 06:37:49

回答

43

答案很複雜。

  • 如果你的servlet是在Web服務器是一個背後的反向代理或負載均衡器上運行,那麼Web代理可以被配置成噴射請求頭,讓該請求所來自的IP地址。不同的反向代理將注入不同的頭文件。請查閱您的(前端)服務器的文檔。

  • 如果您的客戶端使用(轉發)代理,那麼它可能會插入標頭來說什麼客戶端IP地址是...或者它可能不會。並且它插入的IP地址可能不正確。

  • 通過調用request.getRemoteAddr()得到的值將是該請求的上游源直接的IP地址。

您列出的所有標題都不是標準的,但「x-forwarded-for」被認爲是事實標準;即它是最有可能被代理人插入的那個等等......如果有什麼被注入的話。

最後,即使您確實得到了IP地址,也不一定能幫到您。例如,如果客戶端位於專用網絡並通過NAT網關連接到互聯網,則HTTP請求中的IP地址將是NAT服務器的地址...而不是實際的客戶端IP。


那麼這是什麼意思?那麼基本上,這意味着一般你不能可靠找出請求來源系統的IP地址。

+0

非常感謝您的回答,我們使用nginx + tomcat + spring + spring mvc + mybatis,我在中國,這是我在stackoverflow上的第二個問題,我的第一個失敗 - !.我認爲我們應該對它做更多的測試。 – sprite

+0

@sprite - 你應該檢查nginx文檔來找出它使用的是什麼頭。但是,這隻會給你下一個上游主機的IP地址......這可能不是真正的客戶端。正如我所說的,你不可能總是得到真正的客戶IP ......即使你可以,它也不一定是可靠的,有用的或獨特的。 –

+0

好吧,我幾乎能理解你的建議。 '下一個上游主機的IP地址'是否意味着最後一個代理的IP地址?@Stephen C – sprite

8

這似乎是最讓我們可以做的就是客戶端的原始IP地址

String ipAddress = request.getHeader("X-FORWARDED-FOR"); 
if (ipAddress == null) { 
    ipAddress = request.getRemoteAddr(); 
} 
+0

非常感謝 – sprite

+5

除當它不;看我的答案。 –

+7

這是行不通的,因爲X-Forwarded-For可以包含逗號分隔(可選地帶有空格)的代理IP地址列表! – Yeti

相關問題