【问题标题】:HttpServletRequest getRemoteAddr() not working how I would expectHttpServletRequest getRemoteAddr() 无法正常工作
【发布时间】:2012-08-18 07:35:15
【问题描述】:

据我了解,以下代码返回不正确:

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() 返回无效格式,我将如何测试 localhost,或者我做错了什么?

谢谢!

【问题讨论】:

    标签: java servlets localhost


    【解决方案1】:

    0:0:0:0:0:0:0:1%0 是 IPv6 本地主机的有效长格式。 %0 指定可选区域索引。

    这里有更多关于IPv6 Zone Indices的信息。

    我不知道为什么对httpRequest.getRemoteAddr(); 的调用会返回%0 的可选区域索引,并且

    InetAddress.getAllByName("localhost") 
    

    没有。但是,我的建议是,如果您要在 localhost 上进行匹配,请同时匹配两种模式,或者进行 startsWith 匹配。

    【讨论】:

    • 很高兴知道,但奇怪的是它们返回了不同的结果。但是,我不想检查包含或startsWith。奇怪的情况太多:192.168.100.1 > 192.168.100.12等
    • InetAddress 的文档说“可能包括范围索引”,所以这样不高兴...download.java.net/jdk7/archive/b123/docs/api/java/net/…
    • 我想当我提到“匹配两种模式或做一个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
    【解决方案2】:

    问题在于这两个函数

    1) java.net.InetAddress.getAllByName(String)

    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 了解更多信息。

    【讨论】:

    • +1 以获得良好的信息/考虑 Java 运行时与容器以执行这两种方法。
    猜你喜欢
    • 2012-02-14
    • 1970-01-01
    • 2016-12-01
    • 2016-01-02
    • 1970-01-01
    • 2016-09-01
    • 2012-07-11
    • 2018-04-08
    • 2017-04-20
    相关资源
    最近更新 更多