【问题标题】:Proper way to check for URL equality检查 URL 相等性的正确方法
【发布时间】:2011-04-15 19:48:41
【问题描述】:

我有以下场景:

URL u1 = new URL("http://www.yahoo.com/");
URL u2 = new URL("http://www.yahoo.com");

if (u1.equals(u2)) {
    System.out.println("yes");
}
if (u1.toURI().equals(u2.toURI())) {
    System.out.println("uri equality");
}
if (u1.toExternalForm().equals(u2.toExternalForm())) {
    System.out.println("external form equality");
}
if (u1.toURI().normalize().equals(u2.toURI().normalize())) {
    System.out.println("uri normalized equality");
}

这些检查都没有成功。只有路径不同:u1 的路径为“/”,而 u2 的路径为“”。这些 URL 是否指向相同的资源,有没有办法让我在不打开连接的情况下检查这样的事情?我是否误解了有关 URL 的一些基本内容?

编辑 我应该声明需要非 hacky 检查。说空路径 == / 是否合理?我希望没有这种代码

【问题讨论】:

    标签: java url


    【解决方案1】:

    您始终可以将相对 URL 与 Path.equals-method 进行比较

    例如

    Paths.get("/user/login").equals(Paths.get("/user/login/")))
    

    产生真实

    你也可以使用startsWith/endsWith-methods

    【讨论】:

    • 没有像 Paths 这样的类
    • java.nio.file 中有Paths。对于 Android,需要 API 26+。
    【解决方案2】:

    从 2007 年的 JavaOne 开始:

    第二个谜题恰如其分地命名为“More Joys of Sets”,让用户创建包含多个 URL 对象的 HashMap 键。再次,大多数观众无法猜出正确答案。

    观众在这里学到的重要一点是,URL 对象的 equals() 方法实际上已损坏。在这种情况下,如果两个 URL 对象解析为相同的 IP 地址和端口,则它们是相等的,而不仅仅是它们具有相等的字符串。然而,Bloch 和 Pugh 指出了一个更严重的致命弱点:平等行为会有所不同,具体取决于您是否连接到网络,虚拟地址可以解析到同一主机,或者您是否不在网络上,其中 resolve 是一个阻塞操作。因此,就经验教训而言,他们建议:

    不要使用网址;改用 URI。 URI 不尝试比较地址或端口。此外,请勿将 URL 用作 Set 元素或 Map 键。
    对于 API 设计者,equals() 方法不应该依赖于环境。例如,在这种情况下,如果计算机连接到 Internet 而不是独立计算机,则平等不应改变。


    来自 URI 等于文档:

    要使两个分层 URI 被视为相等,它们的路径必须相等并且它们的查询必须要么未定义要么相等。

    在您的情况下,这两条路径是不同的。一个是“/”,另一个是“”。


    根据 URI RFC §6.2.3:

    实现可能在进一步处理时使用特定于方案的规则 成本,以减少假阴性的可能性。例如, 因为“http”方案使用了权限组件,所以有一个 默认端口为“80”,并定义一个空路径等价于 “/”,以下四个URI是等价的:

     http://example.com
     http://example.com/
     http://example.com:/
     http://example.com:80/
    

    这个实现似乎没有使用特定于方案的规则。


    资源:

    【讨论】:

    • ...这根本不能回答问题。
    • 有趣.. 但是如果它们实际上相等,那么 toURI() 测试就会成功。
    • @Colin,现在 this 回答了这个问题。 :)
    • 谢谢!出于好奇,您为什么将其设为社区 wiki?
    • @SB,我希望有人可以帮助我填补空白。好吧,我自己做了这一切:) @Zarel,不完全是,我仍在寻找一种方法来进行平等检查:)
    【解决方案3】:

    严格来说,它们相等。 可选 斜杠 (/) 只是一种常见用法,但不是必须的。您可以显示不同的页面

    http://www.yahoo.com/foo/
    

    为了

    http://www.yahoo.com/foo
    

    你提供的那个甚至是可能的,我相信 HTTP 标头可以跳过那个斜线。

    【讨论】:

    • 对,但是有没有逻辑可以改变 www.yahoo.com 和 www.yahoo.com/ ?
    • example.com/foo/example.com/foo 是不同的,是的,但是 example.comexample.com/ 完全一样。
    猜你喜欢
    • 2018-09-01
    • 2016-12-24
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多