JavaのURIとは?

URI(Uniform Resource Identifier)は、リソースが指し示す場所を一意に参照するための識別子です。
URI参照の構文は次のようになります。
[スキーム:]スキーム固有部分[#フラグメント]
[](ブラケット)はオプションのコンポーネントを表し、「:」と「#」はその文字自体を表しています。
また、スキームを指定しているものが「絶対URI」と呼ばれ、絶対でないURIは「相対URI」と呼ばれます。
URIは、不透明か階層的であるかによって分類のされ方が代わります。
不透明URIは、スキーム固有部分が「/(スラッシュ)」で始まらない絶対URIになり、それ以上解析されません。
不透明URIの例は次の通りです。
mailto:java-net@java.sun.com news:comp.lang.java urn:isbn:096139210x
一方、階層URIは、スキーム固有部分が「/」で始まる絶対URI、もしくはスキームを指定しない相対URIです。
階層URIの例は以下の通りです。
http://java.sun.com/j2se/1.3/docs/guide/collections/designfaq.html#28../../../demo/jfc/SwingSet2/src/SwingSet2.javafile:///~/calendar
階層URIは、構文に沿って以下のように解析できます。
[スキーム:][//機関][パス][?クエリー][#フラグメント]
「:」「/」「?」「#」は、URI参照の構文同様にその文字自体を表します。
階層URIのスキーム固有部分は、スキームとフラグメント・コンポーネントの間の文字で構成されています。
URIクラスで使用できるメソッドは次の通りです。
| 修飾子と型 | メソッドと説明 |
|---|---|
| int | compareTo(URI that) URIを別のオブジェクトと比較し、オブジェクトはURIである必要がある |
| static | URI create(String str) 指定された文字列を解析してURIを作成 |
| boolean | equals(Object ob) URIが別のオブジェクトと等しいかを判定 |
| String | getAuthority() URIのデコードされた機関コンポーネントを返却 |
| String | getFragment() URIのデコードされたフラグメント・コンポーネントを返却 |
| String | getHost() URIのホスト・コンポーネントを返却 |
| String | getPath() URIのデコードされたパス・コンポーネントを返却 |
| int | getPort() URIのポート番号を返却 |
| String | getQuery() URIのデコードされたクエリー・コンポーネントを返却 |
| String | getRawAuthority() URIのそのままの機関コンポーネントを返却 |
| String | getRawFragment() URIのそのままのフラグメント・コンポーネントを返却 |
| String | getRawPath() URIのそのままのパス・コンポーネントを返却 |
| String | getRawQuery() URIのそのままのクエリー・コンポーネントを返却 |
| String | getRawSchemeSpecificPart() URIのそのままのスキーム固有部分を返却 |
| String | getRawUserInfo() URIのそのままのユーザー情報コンポーネントを返却 |
| String | getScheme() URIのスキーム・コンポーネントを返却 |
| String | getSchemeSpecificPart() URIのデコードされたスキーム固有部分を返却 |
| String | getUserInfo() URIのデコードされたユーザー情報コンポーネントを返却 |
| int | hashCode() URIのハッシュ・コード値を返却 |
| boolean | isAbsolute() URIが絶対かどうかを通知 |
| boolean | isOpaque() URIが不透明かどうかを通知 |
| URI | normalize() URIのパスを正規化 |
| URI | parseServerAuthority() URIの機関コンポーネント(定義されている場合)から ユーザー情報・ホスト・ポートの各コンポーネントへの解析を試みる |
| URI | relativize(URI uri) 指定されたURIをURIに対して相対化 |
| URI | resolve(String str) 指定された文字列を解析し、その後に文字列をURIに対して解決して、 新しいURIを構築 |
| URI | resolve(URI uri) 指定されたURIをURIに対して解決 |
| String | toASCIIString() URIのコンテンツをUS-ASCII文字列として返却 |
| String | toString() URIのコンテンツを文字列として返却 |
| URL | toURL() URIからURLを構築 |
URIの生成・組み立て方法

URIの生成・組み立て方法として、サンプルコードを紹介します。
■記述例
import java.net.URI;
public class Main {
public static void main(String[] args) throws Exception {
URI u = new URI("https://style.potepan.com/articles/20674.html#Java");
System.out.println("---コンストラクタの引数が1つの場合、URI文字列を解析する---");
System.out.println(u.getScheme());
System.out.println(u.getHost());
System.out.println(u.getPath());
System.out.println(u.getFragment());
u = new URI("mailto", "sample@potepan.com", "dummy");
System.out.println("---コンストラクタの引数が3つの場合(スキーマ, スキーマ固有部分, フラグメント)---");
System.out.println(u.toASCIIString());
u = new URI("https", "//style.potepan.com/articles/20674.html", "Java");
System.out.println("---コンストラクタの引数が3つの場合でもホスト・パスは認識されます---");
System.out.println(u.getHost());
System.out.println(u.getPath());
u = new URI("https", "style.potepan.com", "/articles/20674.html", "Java");
System.out.println("---コンストラクタの引数が4つの場合---");
System.out.println(u.toASCIIString());
u = new URI("https", "style", "potepan.com", 8080, "/articles", "q=20674", "Java");
System.out.println("---コンストラクタの引数が7つの場合---");
System.out.println(u.toASCIIString());
u = new URI("https", null, "style.potepan.com", -1, "/articles/20674.html", null, "Java");
System.out.println("---コンストラクタの引数が7つの場合、-1を指定するとポートを省略できます---");
System.out.println(u.toASCIIString());
u = new URI(null, null, "articles/../20674", "Java");
System.out.println("---相対URIの場合---");
System.out.println(u.toASCIIString());
System.out.println("---絶対URIなのに相対パスを指定してしまうと例外が発生します---");
try {
u = new URI("https", "style.potepan.com", "Java", null);
} catch (Exception e) {
System.out.println(e);
}
u = new URI(null, null, "articles/../20674", "Java").normalize();
System.out.println("---正規化(normalize)の場合---");
System.out.println(u.toASCIIString());
u = new URI("https", "style.potepan.com", "/articles/none/none", null);
System.out.println("---解決(resolve)の場合---");
u = u.resolve("../20674.html");
System.out.println(u.toASCIIString());
u = new URI("https", "style.potepan.com", "/articles/java/none/", null);
u = u.resolve("../20674.html");
System.out.println(u.toASCIIString());
u = new URI("https", "style.potepan.com", "/articles/none/none", null);
System.out.println("---すでに絶対URIの場合、そのまま返します---");
u = u.resolve(new URI("https", "style.potepan.com", "/articles", null));
System.out.println(u.toASCIIString());
System.out.println("---相対化の場合---");
URI u1 = new URI("https://style.potepan.com/articles/20674.html/Java");
URI u2 = new URI("https://style.potepan.com/articles");
URI rel = null;
rel = u2.relativize(u1);
System.out.println(rel.toASCIIString());
rel = u1.relativize(u2);
System.out.println(rel.toASCIIString());
u = new URI("mailto:sample@potepan.com");
System.out.println("---不透明URI (cf. 階層URI)の場合---");
System.out.println(u.getScheme());
System.out.println(u.getSchemeSpecificPart());
System.out.println(u.getHost());
System.out.println(u.getPath());
u = new URI("urn:isbn:09876543x");
System.out.println("---スキーマ固有部分にコロンを含む場合もあります---");
System.out.println(u.getScheme());
System.out.println(u.getSchemeSpecificPart());
}
}
■実行結果 mbp:desktop potepan$ java Main ---コンストラクタの引数が1つの場合、URI文字列を解析する--- https style.potepan.com /articles/20674.html Java ---コンストラクタの引数が3つの場合(スキーマ, スキーマ固有部分, フラグメント)--- mailto:sample@potepan.com#dummy ---コンストラクタの引数が3つの場合でもホスト・パスは認識されます--- style.potepan.com /articles/20674.html ---コンストラクタの引数が4つの場合---【Java】大人気の開発言語”Java”とは?概要~使い方まで初心者にもわかりやすく解説。---コンストラクタの引数が7つの場合--- https://style@potepan.com:8080/articles?q=20674#Java ---コンストラクタの引数が7つの場合、-1を指定するとポートを省略できます---【Java】大人気の開発言語”Java”とは?概要~使い方まで初心者にもわかりやすく解説。---相対URIの場合--- articles/../20674#Java ---絶対URIなのに相対パスを指定してしまうと例外が発生します--- java.net.URISyntaxException: Relative path in absolute URI: https://style.potepan.comJava ---正規化(normalize)の場合--- 20674#Java ---解決(resolve)の場合---【Java】大人気の開発言語”Java”とは?概要~使い方まで初心者にもわかりやすく解説。https://style.potepan.com/articles/java/20674.html ---すでに絶対URIの場合、そのまま返します---articles---相対化の場合--- 20674.html/Javaarticles---不透明URI (cf. 階層URI)の場合--- mailto sample@potepan.com null null ---スキーマ固有部分にコロンを含む場合もあります--- urn isbn:09876543x
URIとURLの違いは?

URIは、指定のURIと他URIの指し示すものが同一であるか、ベースURIと相対URIを解決して新しいURIを作成するといった操作がメインのクラスです。
一方、URL(Uniform Resource Locator)は、何かしらのリソースが存在することを表現するものです。
リソースは、ファイル・ディレクトリのような単純なものである場合や、データベース・検索エンジンに対するクエリーなど、複雑なオブジェクトへの参照である場合などがあります。
URLはURIでできる単純な文字列表現だけではなく、リソースにアクセスするための手段もあわせて提供しているのです。