我可以用什么java库来比较两个URL是否相等?

时间:2013-08-16 19:33:51

标签: java 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

这些网址不相同:

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 {
//...?
    }

}

2 个答案:

答案 0 :(得分:8)

java.net.URI会比较两个没有网络请求的网址(the way java.net.URL does),您可以使用normalize方法制作一个带有绝对路径路径规范的网址。

您的示例存在一些问题:

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不是有效的URL,尽管大多数用户代理都同意如何将前者转换为后者。

答案 1 :(得分:1)

从2018年更新

OkHttp Library可以正确比较网址。

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

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

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

stackoverflow.com
www.stackoverflow.com

你可以这样做:

HttpUrl url = HttpUrl.parse("http://google.com");
return url.equals(url2);