检查URL相等性的正确方法

我有以下情况:

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检查。 说空路径== /?是否合理? 我希望没有这种代码

从2007 JavaOne:

第二个难题,恰如其分地命名为“更多集合的欢乐”,用户可以创建包含多个URL对象的HashMap键。 同样,大多数观众都无法猜出正确的答案。

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

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


从URI等于文档:

要使两个分层URI相等, 它们的路径必须相等,并且它们的查询必须都是未定义的,否则必须相等。

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


根据URIRFC§6.2.3:

实现可以以进一步的处理成本使用特定于方案的规则,以降低漏报的可能性。 例如,因为“http”方案使用权限组件,默认端口为“80”,并且定义了一个等同于“/”的空路径,所以以下四个URI是等效的:

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

似乎此实现不使用特定于方案的规则。


资源:

  • sun.com – Java Puzzlers服务于Brain Benders Galore
  • javadoc – URI.equals()
  • URI RFC

严格来说,他们并不平等。 可选的尾部斜杠(/)仅是常见用法,但不是必须的。 您可以显示不同的页面

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

并为

 http://www.yahoo.com/foo 

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

您始终可以使用Path.equals-method比较相对URL

恩。

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

产生真实

您还可以使用startsWith / endsWith-methods