2012-08-22 17 views
6

下面的代碼返回錯誤,從我的理解:的HttpServletRequest的getRemoteAddr()不工作我怎麼會想到

HttpServletRequest httpRequest = (HttpServletRequest) request; 
String userIPAddress = httpRequest.getRemoteAddr(); 

// Actual 
// "0:0:0:0:0:0:0:1%0" 

// Expected 
// "0:0:0:0:0:0:0:1" 

任何想法,爲什麼%0是存在的?當我依次通過

InetAddress.getAllByName("localhost") 

我得到如下:

// ["192.168.100.1", "127.0.0.1", "0:0:0:0:0:0:1"] 

我怎麼會測試本地主機,如果的getRemoteAddr()將返回無效的格式,還是我做錯了什麼?

謝謝!

回答

4

的問題是這兩種功能

1)java.net.InetAddress.getAllByName(字符串)

2)javax.servlet.ServletRequest.getRemoteAddr()

是非常不同的。第一個函數是標準Java運行時的一部分,第二個函數是由Java EE容器實現的。您正在使用Tomcat7,因此正在添加可選的區域參數%0。

底線,你不應該像你一樣在IP地址上進行字符串比較。

你真正應該做的是使用org.apache.catalina.filters.RemoteIpFilter。這就是你想要以明確的方式來做的事情。

例子:

<filter> 
    <filter-name>RemoteIpFilter</filter-name> 
    <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class> 
    <init-param> 
    <param-name>allowedInternalProxies</param-name> 
    <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value> 
    </init-param> 
    <init-param> 
    <param-name>remoteIpHeader</param-name> 
    <param-value>x-forwarded-for</param-value> 
    </init-param> 
    <init-param> 
    <param-name>remoteIpProxiesHeader</param-name> 
    <param-value>x-forwarded-by</param-value> 
    </init-param> 
    <init-param> 
    <param-name>protocolHeader</param-name> 
    <param-value>x-forwarded-proto</param-value> 
    </init-param> 
</filter> 

更多信息,請參見http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#Remote_IP_Filter

+0

+1,以獲得關於Java運行時和容器兩種方法執行的良好信息/想法。 –

+0

謝謝菲利普。 –

2

0:0:0:0:0:0:0:1%0是IPv6本地主機的有效長格式。 %0指定了可選的區域索引。

這是關於IPv6 Zone Indices的更多信息。

我不知道爲什麼到httpRequest.getRemoteAddr();呼叫返回的0%的可選的區域索引,

InetAddress.getAllByName("localhost") 

沒有。但是,我的建議是,如果您希望在本地主機上匹配,則可以匹配兩種模式,或者執行startsWith匹配。

+0

這很好知道,他們返回不同的結果很奇怪。但是,我不想檢查是否包含或開始使用。太多奇怪的情況:192.168.100.1> 192.168.100.12等 – andrewpthorp

+1

InetAddress文檔說「可能包括範圍索引」,所以沒有喜悅的方式... http://download.java.net/jdk7/archive/b123/ docs/api/java/net/InetAddress.html#getAllByName%28java.lang.String%29 – Alfabravo

+0

我想當我提到「匹配兩種模式或做一個startsWith匹配」時我有點含糊。請允許我澄清。你的問題明確提到由於後面的'%0'而無法匹配。爲了匹配IPv6地址,您應該忽略可選的區域索引,並且匹配'0:0:0:0:0:0:0:1'。這個可選的區域索引將取決於操作系統。例如,在Linux上,您的IPv6回送可以是'0:0:0:0:0:0:0:1%eth0',而在Windows上,它可以是'0:0:0:0:0:0:0: 1%0' –

相關問題