7

这个问题在这里被问过:

但我对答案完全不满意。我需要一种方法来比较两个 URL 是否相等,理想情况下我不会手动编写它。这个库需要明白这些 url 是相等的

http://stackoverflow.com
https://stackoverflow.com/

https://stackoverflow.com/questions/ask
https://stackoverflow.com/questions/ask/

http://stackoverflow.com?paramName=
http://stackoverflow.com?paramName

http://stackoverflow.com?paramName1=value1&paramName2=value2
http://stackoverflow.com?paramName2=value2&paramName1=value1

http://stackoverflow.com?param name 1=value 1
http://stackoverflow.com?param%20name%201=value%201

这些 URL 不相等:

https://stackoverflow.com/questions/ask
https://stackoverflow.com/questionz/ask

http://stackoverflow.com?paramName1=value1&paramName2=value2
http://stackoverflow.com?paramName1=value1&paramName2=value3

像这样的其他复杂的事情。我在哪里可以找到这样的图书馆?

顺便说一句,这是一个单元测试:

import org.junit.Test;

import java.net.URI;
import java.net.URISyntaxException;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;

public class UriTest {

    @Test
    public void equality() throws URISyntaxException {
        assertUrlsEqual("http://stackoverflow.com", "https://stackoverflow.com/");
        assertUrlsEqual("https://stackoverflow.com/questions/ask", "https://stackoverflow.com/questions/ask/");
        assertUrlsEqual("http://stackoverflow.com?paramName=", "http://stackoverflow.com?paramName");
        assertUrlsEqual("http://stackoverflow.com?paramName1=value1&paramName2=value2", "http://stackoverflow.com?paramName2=value2&paramName1=value1");
        assertUrlsEqual("http://stackoverflow.com?param name 1=value 1", "http://stackoverflow.com?param%20name%201=value%201");
    }

    @Test
    public void notEqual() throws URISyntaxException {
        assertUrlsNotEqual("https://stackoverflow.com/questions/ask", "https://stackoverflow.com/questionz/ask");
        assertUrlsNotEqual("http://stackoverflow.com?paramName1=value1&paramName2=value2", "http://stackoverflow.com?paramName1=value1&paramName2=value3");
    }

    private void assertUrlsNotEqual(String u1, String u2) throws URISyntaxException {

//...?
    }

    private void assertUrlsEqual(String u1, String u2) throws URISyntaxException {
//...?
    }

}
4

2 回答 2

8

java.net.URI将比较两个没有网络请求的 URL(方式java.net.URL),并且您可以使用该normalize方法制作具有绝对路径 path-canonical 的 URL。

您的示例存在一些问题:

http://stackoverflow.com?paramName=
http://stackoverflow.com?paramName

http://stackoverflow.com?paramName1=value1&paramName2=value2
http://stackoverflow.com?paramName2=value2&paramName1=value1

允许服务器为参数的顺序和等号的存在赋予意义,因此根据RFC 3986 ,这些对是不等价的。

http://stackoverflow.com?param name 1=value 1
http://stackoverflow.com?param%20name%201=value%201

并非所有 URL 库都将这些视为有效,因为根据 RFC 3986,第一个不是有效 URL,尽管大多数用户代理同意如何将前者转换为后者。

于 2013-08-16T19:39:53.773 回答
1

2018 年更新

有一个OkHttp 库可以以正确的方式比较 URL。

以下是关于它的文章 - https://medium.com/square-corner-blog/okhttps-new-url-class-515460eea661http://square.github.io/okhttp/

但请记住,它认为这些是不同的 URL:

http://stackoverflow.com
https://stackoverflow.com

stackoverflow.com
www.stackoverflow.com

你可以这样做:

HttpUrl url = HttpUrl.parse("http://google.com");
return url.equals(url2);
于 2018-04-12T12:30:14.500 回答