1. 概要

この短い記事では、URIとURLの主な違いを見て、それらの違いを強調するための例を実装します。

2. URIとURL

それらの定義を知っていれば、それらの違いは簡単です。

  • Unix Resource Identifier(URI)-抽象または物理リソースの完全な識別を可能にする文字のシーケンス
  • Unix Resource Locator(URL)-リソースが利用可能な場所を識別することに加えて、リソースにアクセスするための主要なメカニズムを記述するURIのサブセット。

これで、すべてのURLがURI であると結論付けることができますが、後で説明するように、その逆は当てはまりません。

2.1. 構文

URLであるかどうかに関係なく、すべてのURIは特定の形式に従います。

scheme:[//authority][/path][?query][#fragment]

各部分は次のように説明されています。

  • schema -URLの場合、リソースへのアクセスに使用されるプロトコルの名前です。他のURIの場合、そのスキーム内で識別子を割り当てるための仕様を参照する名前です。
  • 権限-ユーザー認証情報、ホスト、およびオプションのポートで構成されるオプションの部分
  • pathスキームおよび権限のスコープ内のリソースを識別するのに役立ちます
  • query パスとともに、がリソースを識別するのに役立つ追加データ。 URLの場合、これはクエリ文字列です
  • Fragment-リソースの特定の部分に対するオプションの識別子

特定のURIがURLでもあるかどうかを簡単に識別するために、そのスキームを確認できます。 すべてのURLは、 ftp http https、 gopher mailtoのいずれかのスキームで始まる必要があります。 、 news nntp telnet wais file 、またはprospero。 それで始まらない場合、それはURLではありません。

構文がわかったので、いくつかの例を見てみましょう。 これがURIのリストです。最初の3つだけがURLです。

ftp://ftp.is.co.za/rfc/rfc1808.txt
https://tools.ietf.org/html/rfc3986
mailto:[email protected]

tel:+1-816-555-1212
urn:oasis:names:docbook:dtd:xml:4.1
urn:isbn:1234567890

3. URIとURLのJavaAPIの違い

このセクションでは、Javaが提供するURIクラスとURLクラスの主な違いを例を挙げて説明します。

3.1. インスタンス化

URIインスタンスとURLインスタンスの作成は非常に似ており、どちらのクラスもその部分のほとんどを受け入れるいくつかのコンストラクターを提供しますが、URIクラスのみが指定するコンストラクターを持っています構文のすべての部分:

@Test
public void whenCreatingURIs_thenSameInfo() throws Exception {
    URI firstURI = new URI(
      "somescheme://theuser:thepassword@someauthority:80"
      + "/some/path?thequery#somefragment");
    
    URI secondURI = new URI(
      "somescheme", "theuser:thepassword", "someuthority", 80,
      "/some/path", "thequery", "somefragment");

    assertEquals(firstURI.getScheme(), secondURI.getScheme());
    assertEquals(firstURI.getPath(), secondURI.getPath());
}

@Test
public void whenCreatingURLs_thenSameInfo() throws Exception {
    URL firstURL = new URL(
      "http://theuser:thepassword@somehost:80"
      + "/path/to/file?thequery#somefragment");
    URL secondURL = new URL("http", "somehost", 80, "/path/to/file");

    assertEquals(firstURL.getHost(), secondURL.getHost());
    assertEquals(firstURL.getPath(), secondURL.getPath());
}

URI クラスは、チェックされた例外をスローしない新しいインスタンスを作成するためのユーティリティメソッドも提供します。

@Test
public void whenCreatingURI_thenCorrect() {
    URI uri = URI.create("urn:isbn:1234567890");
    
    assertNotNull(uri);
}

The URL class doesn’t provide such a method.

URLは前述のスキームのいずれかで開始する必要があるため、別のスキームでオブジェクトを作成しようとすると、例外が発生します。

@Test(expected = MalformedURLException.class)
public void whenCreatingURLs_thenException() throws Exception {
    URL theURL = new URL("otherprotocol://somehost/path/to/file");

    assertNotNull(theURL);
}

両方のクラスに他のコンストラクターがあります。それらすべてを見つけるには、URIおよびURLのドキュメントを参照してください。

3.2. URIインスタンスとURLインスタンス間の変換

URIとURL間の変換は非常に簡単です。

@Test
public void givenObjects_whenConverting_thenCorrect()
  throws MalformedURLException, URISyntaxException {
    String aURIString = "http://somehost:80/path?thequery";
    URI uri = new URI(aURIString);
    URL url = new URL(aURIString);

    URL toURL = uri.toURL();
    URI toURI = url.toURI();

    assertNotNull(url);
    assertNotNull(uri);
    assertEquals(toURL.toString(), toURI.toString());
}

ただし、URL以外のURIを変換しようとすると、例外が発生します。

@Test(expected = MalformedURLException.class)
public void givenURI_whenConvertingToURL_thenException()
  throws MalformedURLException, URISyntaxException {
    URI uri = new URI("somescheme://someauthority/path?thequery");

    URL url = uri.toURL();

    assertNotNull(url);
}

3.3. リモート接続を開く

URLはリモートリソースへの有効な参照であるため、Javaは、そのリソースへの接続を開き、そのコンテンツを取得するためのメソッドを提供します。

@Test
public void givenURL_whenGettingContents_thenCorrect()
  throws MalformedURLException, IOException {
    URL url = new URL("http://courses.baeldung.com");
    
    String contents = IOUtils.toString(url.openStream());

    assertTrue(contents.contains("<!DOCTYPE html>"));
}

It should be noted that the implementation of the URL equals() and hashcode() functions may trigger the DNS naming service to resolve the IP address. This is inconsistent and can give different results depending on the network connection and also takes a long time to run. The implementation is known to be incompatible with virtual hosting and should not be used. We recommend using URI instead.

4. Conclusion

この簡単な記事では、JavaのURIURLの違いを示すいくつかの例を紹介しました。

両方のオブジェクトのインスタンスを作成するときと、一方のオブジェクトをもう一方のオブジェクトに変換するときの違いを強調しました。 また、URLにはポイントされたリソースへのリモート接続を開くメソッドがあることも示しました。

いつものように、この記事の完全なソースコードは、Githubにあります。