检查URL相等性的正确方法

时间:2010-09-22 15:48:34

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

3 个答案:

答案 0 :(得分:26)

来自2007 JavaOne:

  

第二个谜题,名为“More Joys of Sets”,用户可以创建包含多个URL对象的HashMap键。同样,大多数观众都无法猜出正确答案。

     

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

     

不要使用网址;使用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/

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


资源:

答案 1 :(得分:2)

严格来说,他们相等。 可选尾部斜杠(/)只是常用用法,但不是必须的。您可以显示

的不同页面
http://www.yahoo.com/foo/

http://www.yahoo.com/foo

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

答案 2 :(得分:0)

您始终可以使用Path.equals-method

比较相对网址

离。

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

生成 true

您还可以使用startsWith / endsWith-methods