URLとURIの違い
1. 概要
この短い記事では、URIとURLの主な違いを確認し、それらの違いを強調するための例を実装します。
2. URIとURL
それらの違いは、それらの定義を知った後は簡単です:
-
Uniform Resource Identifier (URI)-抽象リソースまたは物理リソースの完全な識別を可能にする文字のシーケンス
-
Uniform Resource Locator (URL)-リソースが利用可能な場所を特定することに加えて、リソースにアクセスするための主要なメカニズムを説明するURIのサブセット
Now we can conclude that every URL is a URIですが、後で説明するように、その逆は当てはまりません。
2.1. 構文
すべてのURIは、URLであるかどうかに関係なく、特定の形式に従います。
scheme:[//authority][/path][?query][#fragment]
各部分の説明は次のとおりです。
-
scheme-URLの場合、リソースへのアクセスに使用されるプロトコルの名前、他のURIの場合、そのスキーム内で識別子を割り当てるための仕様を参照する名前です。
-
authority-ユーザー認証情報、ホスト、およびオプションのポートで構成されるオプションの部分
-
path-schemeおよびauthorityのスコープ内のリソースを識別するのに役立ちます
-
query-path,とともにリソースを識別するのに役立つ追加データ。 URLの場合、これはクエリ文字列です
-
fragment-リソースの特定の部分に対するオプションの識別子
To easily identify if a particular URI is also a URL, we can check its scheme。 すべての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:[email protected]: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:[email protected]: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);
}
URLクラスはそのようなメソッドを提供しません。
URLは前述のスキームのいずれかで開始する必要があるため、別のスキームでオブジェクトを作成しようとすると、例外が発生します。
@Test(expected = MalformedURLException.class)
public void whenCreatingURLs_thenException() throws Exception {
URL theURL = new URL("otherprotocol://somehost/path/to/file");
assertNotNull(theURL);
}
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.example.com");
String contents = IOUtils.toString(url.openStream());
assertTrue(contents.contains(""));
}
4. 結論
この簡単な記事では、JavaのURIとURLの違いを示すいくつかの例を紹介しました。
両方のオブジェクトのインスタンスを作成するときと、一方のオブジェクトを他方に変換するときの違いを強調しました。 また、URLには、指定されたリソースへのリモート接続を開くメソッドがあることも示しました。
いつものように、この記事の完全なソースコードはover on Githubにあります。