7

この質問はここで尋ねられました:

しかし、私は答えに完全に満足していません。2 つの 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は、ネットワーク リクエストなしで 2 つの URL を比較します (方法java.net.URLはそうです)。このnormalizeメソッドを使用して、絶対パスを含む URL を path-canonical にすることができます。

あなたの例にはいくつかの問題があります:

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 ライブラリがこれらを有効なものとして扱うわけではありませんが、ほとんどのユーザー エージェントは前者を後者に変換する方法について合意しています。

于 2013-08-16T19:39:53.773 に答える