S-JIS[2010-01-22] 変更履歴

URI

java.net.URIクラスは、URIを扱うクラス。JDK1.4以降。
このクラスは不変オブジェクト。


URI生成例

コンストラクターでは、生成したURIが間違った形式の時はURISyntaxExceptionが発生する。
create()メソッドだと、間違っていたらIllegalArgumentExceptionが発生する(RuntimeException系なので、明示的にcatchを書く必要が無い)。プログラムで生成したURI文字列を渡すなど、「間違っていないはず」の場合に使用する。

名前 引数 throws 概要
URI String str URISyntaxException コンストラクター new URI("scheme://userInfo@host:1024/path?query#fragment")
new URI("path")
new URI("http://localhost:8080/sample.do?param=zzz")
new URI("../common.css")
create String str   URI(str)と同様。 URI.create("scheme://userInfo@host:1024/path?query#fragment")
URI String scheme
String userInfo
String host
int port
String path
String query
String fragment
URISyntaxException コンストラクター new URI("scheme", "userInfo", "host", 1024, "/path", "query", "fragment")

scheme://userInfo@host:1024/path?query#fragment
new URI("scheme", null, "host", 1024, "/path", "query", "fragment")

scheme://host:1024/path?query#fragment
new URI("scheme", null, "host", -1, "/path", "query", "fragment")

scheme://host/path?query#fragment
new URI(null, null, null, -1, "/path", "query", "fragment")

/path?query#fragment
new URI(null, null, null, -1, "path", "query", "fragment")

path?query#fragment
new URI(null, null, null, -1, "path", null, null)

path
new URI(null, null, null, -1, "../common.css", null, null)

../common.css
URI String scheme
String authority
String path
String query
String fragment
URISyntaxException コンストラクター new URI("scheme", "authority", "/path", "query", "fragment")

scheme://authority/path?query#fragment
URI String scheme
String host
String path
String fragment
URISyntaxException コンストラクター
URI(scheme, null, host, -1, path, null, fragment)と同じ。
new URI("scheme", "host", "/path", "fragment")

scheme://host/path#fragment
new URI("scheme", "host", "/path?abc=zzz", "fragment")

scheme://host/path%3Fabc=zzz#fragment
URI String scheme
String ssp
String fragment
URISyntaxException コンストラクター
ssp:scheme-specific-part
new URI("scheme", "ssp", "fragment")

scheme:ssp#fragment
new URI("scheme", "//host:port/path?abc=zzz", "fragment")

scheme://host:port/path?abc=zzz#fragment

URIから別のURIを生成するメソッド。

名前 引数 概要
normalize   正規化されたURIを返す。
基本的に「..」や「.」が解釈されて除去される。
URI uri = new URI("http://host/root/abc/../def/index.html").normalize();

http://host/root/def/index.html
URI uri = new URI("./abc/index.html").normalize();

abc/index.html
URI uri = new URI("../def/index.html").normalize();

../def/index.html
parseServerAuthority   authorityからuserInfo・host・port等を解釈したURIを返す。  
resolve URI uri 自分のURIを基準に、引数で与えられたURIを解釈(正規化)したURIを返す。
(引数が絶対パスの場合は、引数のインスタンスがそのまま返される)
URI base = new URI("http://host/root/abc/index.html");
URI uri  = new URI("../def/zzz.html");
URI res = base.resolve(uri);

http://host/root/def/zzz.html
URI base = new URI("http://host/root/abc/index.html");
URI uri  = new URI("#name");
URI res = base.resolve(uri);

http://host/root/abc/index.html#name
relativize URI uri 引数で与えられたURIの、自分のURIを接頭辞とする相対パスを返す。 URI base = new URI("http://host/root/");
URI uri  = new URI("http://host/root/def/zzz.html");
URI rel = base.relativize(uri);

def/zzz.html
URI base = new URI("http://host/root");
URI uri  = new URI("http://host/root/def/zzz.html");
URI rel = base.relativize(uri);

def/zzz.html
自分のURIが引数のURIの接頭辞(前部分)でない場合、引数のURIインスタンスがそのまま返される。 URI base = new URI("http://host/ro");
URI uri  = new URI("http://host/root/def/zzz.html");
URI rel = base.relativize(uri);

http://host/root/def/zzz.html
URI base = new URI("http://host/root/abc");
URI uri  = new URI("http://host/root/def/zzz.html");
URI rel = base.relativize(uri);

http://host/root/def/zzz.html

relativize()は、「接頭辞として一致するURI」からしか相対URIを生成できないのが残念。


他クラスとURIとの変換。

クラス URIから URIへ 備考
java.io.File URI uri = new URI("file:/C:/abc.txt");
File f = new File(uri);
URI uri = f.toURI(); fileスキーマは「file://ホスト/パス」という形式。
パスは「/」区切りで書く。(Windowsであっても!)
ホスト」を省略すると「file:///パス」、
//ホスト」を省略すると「file:/パス」。
file://C:/temp」と書くと、「//」の直後「C:」がホスト+ポート番号(番号自体は省略)として認識されてしまう。
java.net.URL URL url = uri.toURL(); URI uri = url.toURI();
URI uri = new URI(url.toString());
URL#toURI()はJDK1.5以降。
javax.tools.FileObject   URI uri = fo.toURI();  

判断メソッド

メソッド 内容 備考
isAbsolute() 絶対かどうか。
絶対とは: スキーマが設定されていること
(具体的には、schemeがnull以外の場合、true)
パス部分を指しての「絶対パス(「/」から始まる)」ではないので注意。
そういう意味でファイルの絶対パスFile#isAbsolute()とは異なる。
ただ、相対パスのURIではスキーマは指定できないから、これで正しいのだろう。
「http://ホスト/パス」なら「/パス」がpathなので、相対パスには成り得ない。
「http:パス」という形だとpathに値が設定されないので、httpのURIとしては正しくないのかも。
isOpaque() 不透明かどうか。
不透明とは: 絶対URIであり、スキーマ固有部分が「/」で始まっていないこと
(具体的には、pathがnullの場合、true)
例えば「mailto:user@host」はtrue。
スキーマが指定されており、その「:」の直後が「/」で始まっているかどうかによって、
URIインスタンス生成時にpathが設定されるかどうかが決まるのだと思われる。

値取得メソッド

java.net.URIは不変クラスなので、ゲッターメソッドは有るがセッターメソッドは無い。

通常のクラスではゲッターメソッドはコンストラクターで指定した値をそのまま返す事が多いが、
java.net.URIでは、単なるゲッターメソッドのほとんどはデコードされた文字列を返す。(%XX形式を“人間が読める文字”に変換する)
コンストラクターで指定した値をそのまま取得したい場合は、「getRaw」で始まるゲッターメソッドを使用する。

メソッド 内容 無い場合
getScheme() スキーマ null
getRawSchemeSpecificPart() getSchemeSpecificPart() スキーマ固有部分 null
getRawAuthority() getAuthority() 機関コンポーネント null
getRawUserInfo() getUserInfo() ユーザー情報 null
getHost() ホスト null
getPort() ポート番号 -1
getRawPath() getPath() パス null
getRawQuery() getQuery() クエリー null
getRawFragment() getFragment() フラグメント null
toString() 文字列表現  
  toASCIIString() 文字列表現(UTF-8エンコード  

URLのエンコード・デコードにはURLEncoder・URLDecoderを使うものだと思うが、
java.net.URIの個々のゲッターメソッドのデコードにはCharsetDecoder
toASCIIString()のエンコードにはCharsetEncoderが使われているようだ。

URIクラスでは「scheme」というつづりなので(「schema」という単語は別途あるし)、日本語では「スキーム」が正しいんじゃないかと思わなくもないが、Javadocでは「スキーマ」となっている。
でも確かに「http:」とかを「スキーマ」と呼んでる人の方が多いので、「スキーム」と言われると違和感があるかも(苦笑)


データ取得例

メソッド 内容 データの例
  元データ new URI("http://user@host:1024/path?p1=v1&p2=v2#fragment")
toString() 文字列表現 http://user@host:1024/path?p1=v1&p2=v2#fragment
toASCIIString()
getScheme() スキーマ http
getRawSchemeSpecificPart() スキーマ固有部分 //user@host:1024/path?p1=v1&p2=v2
getSchemeSpecificPart()
getRawAuthority() 機関コンポーネント user@host:1024
getAuthority()
getRawUserInfo() ユーザー情報 user
getUserInfo()
getHost() ホスト host
getPort() ポート番号 1024
getRawPath() パス /path
getPath()
getRawQuery() クエリー p1=v1&p2=v2
getQuery()
getRawFragment() フラグメント fragment
getFragment()
isAbsolute() 絶対 true
isOpaque() 不透明 false
メソッド 内容 データの例
  元データ new URI("http://ユーザー@host:1024/パス?p1=値1&p2=値2#フラグメント")
toString() 文字列表現 http://ユーザー@host:1024/パス?p1=値1&p2=値2#フラグメント
toASCIIString() 文字列表現(UTF-8エンコード http://%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC@host:1024/%E3%83%91%E3%82%B9?p1=%E5%80%A41&p2=%E5%80%A42#%E3%83%95%E3%83%A9%E3%82%B0%E3%83%A1%E3%83%B3%E3%83%88
getScheme() スキーマ http
getRawSchemeSpecificPart() スキーマ固有部分 //ユーザー@host:1024/パス?p1=値1&p2=値2
getSchemeSpecificPart()
getRawAuthority() 機関コンポーネント ユーザー@host:1024
getAuthority()
getRawUserInfo() ユーザー情報 ユーザー
getUserInfo()
getHost() ホスト host
getPort() ポート番号 1024
getRawPath() パス /パス
getPath()
getRawQuery() クエリー p1=値1&p2=値2
getQuery()
getRawFragment() フラグメント フラグメント
getFragment()
isAbsolute() 絶対 true
isOpaque() 不透明 false
メソッド 内容 データの例
  元データ new URI("http://" + URLEncoder.encode("ユーザー", "UTF-8") + "@host:1024" +
"/" + URLEncoder.encode("パス", "UTF-8") +
"?p1=" + URLEncoder.encode("値", "UTF-8") +
"#" + URLEncoder.encode("フラグメント", "UTF-8"))
new URI("http://%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC@host:1024/%E3%83%91%E3%82%B9?p1=%E5%80%A4#%E3%83%95%E3%83%A9%E3%82%B0%E3%83%A1%E3%83%B3%E3%83%88")
toString() 文字列表現 http://%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC@host:1024/%E3%83%91%E3%82%B9?p1=%E5%80%A4#%E3%83%95%E3%83%A9%E3%82%B0%E3%83%A1%E3%83%B3%E3%83%88
toASCIIString() 文字列表現(UTF-8エンコード
getScheme() スキーマ http
getRawSchemeSpecificPart() スキーマ固有部分 //%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC@host:1024/%E3%83%91%E3%82%B9?p1=%E5%80%A4
getSchemeSpecificPart() //ユーザー@host:1024/パス?p1=値
getRawAuthority() 機関コンポーネント %E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC@host:1024
getAuthority() ユーザー@host:1024
getRawUserInfo() ユーザー情報 %E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC
getUserInfo() ユーザー
getHost() ホスト host
getPort() ポート番号 1024
getRawPath() パス /%E3%83%91%E3%82%B9
getPath() /パス
getRawQuery() クエリー p1=%E5%80%A4
getQuery() p1=値
getRawFragment() フラグメント %E3%83%95%E3%83%A9%E3%82%B0%E3%83%A1%E3%83%B3%E3%83%88
getFragment() フラグメント
isAbsolute() 絶対 true
isOpaque() 不透明 false
メソッド 内容 データの例
  元データ new URI("http://host/") new URI("http://host") new URI("../index.html") new URI("/root/index.html") new URI("http:index.html")
new URI("mailto:user@host")
toString() 文字列表現 http://host/ http://host ../index.html /root/index.html http:index.html
mailto:user@host
toASCIIString()
getScheme() スキーマ http http null null http
mailto
getRawSchemeSpecificPart() スキーマ固有部分 //host/ //host ../index.html /root/index.html index.html
user@host
getSchemeSpecificPart()
getRawAuthority() 機関コンポーネント host host null null null
getAuthority()
getRawUserInfo() ユーザー情報 null null null null null
getUserInfo()
getHost() ホスト host host null null null
getPort() ポート番号 -1 -1 -1 -1 -1
getRawPath() パス /   ../index.html /root/index.html null
getPath()
getRawQuery() クエリー null null null null null
getQuery()
getRawFragment() フラグメント null null null null null
getFragment()
isAbsolute() 絶対 true true false false true
isOpaque() 不透明 false false false false true
  備考   パスは空文字列。   パスは「/」から始まっているので
“絶対パス”の様に思えるが、
URIとしては“絶対”ではない。
「スキーマ固有部分」には値があるが、
ユーザー・ホスト等には設定されない。
メソッド 内容 データの例
  元データ new URI("http://host/?query#frag") new URI("http://host?query#frag") new URI("../index.html?query#frag") new URI("/root/index.html?query#frag") new URI("http:index.html?query#frag")
new URI("mailto:user@host?query#frag")
toString() 文字列表現 http://host/?query#frag http://host?query#frag ../index.html?query#frag /root/index.html?query#frag http:index.html?query#frag
mailto:user@host?query#frag
toASCIIString()
getScheme() スキーマ http http null null http
mailto
getRawSchemeSpecificPart() スキーマ固有部分 //host/?query //host?query ../index.html?query /root/index.html?query index.html?query
user@host?query
getSchemeSpecificPart()
getRawAuthority() 機関コンポーネント host host null null null
getAuthority()
getRawUserInfo() ユーザー情報 null null null null null
getUserInfo()
getHost() ホスト host host null null null
getPort() ポート番号 -1 -1 -1 -1 -1
getRawPath() パス /   ../index.html /root/index.html null
getPath()
getRawQuery() クエリー query query query query null
getQuery()
getRawFragment() フラグメント frag frag frag frag frag
getFragment()
isAbsolute() 絶対 true true false false true
isOpaque() 不透明 false false false false true
  備考   パスは空文字列。      
メソッド 内容 データの例
  元データ new File("C:\\temp").toURI() new File("C:\\zzz").toURI() new File("C:\\temp\\foo.txt").toURI() new File("..\\foo.txt").toURI()
存在するディレクトリー 存在しないディレクトリー ファイル 相対パス
toString() 文字列表現 file:/C:/temp/ file:/C:/zzz file:/C:/temp/foo.txt file:/C:/sample/../foo.txt
toASCIIString()
getScheme() スキーマ file file file file
getRawSchemeSpecificPart() スキーマ固有部分 /C:/temp/ /C:/zzz /C:/temp/foo.txt /C:/sample/../foo.txt
getSchemeSpecificPart()
getRawAuthority() 機関コンポーネント null null null null
getAuthority()
getRawUserInfo() ユーザー情報 null null null null
getUserInfo()
getHost() ホスト null null null null
getPort() ポート番号 -1 -1 -1 -1
getRawPath() パス /C:/temp/ /C:/zzz /C:/temp/foo.txt /C:/sample/../foo.txt
getPath()
getRawQuery() クエリー null null null null
getQuery()
getRawFragment() フラグメント null null null null
getFragment()
isAbsolute() 絶対 true true true true
isOpaque() 不透明 false false false false
  備考 f.isDirectory()がtrueになる場合は
パスの末尾に「/」が付く。
f.isDirectory()がfalseになる場合は
ファイル扱い。
  相対パスは、
カレントディレクトリーからのパス
として扱われる。

変換例

ローカルファイルの絶対パスを相対パスに変換する例

基準となる親ディレクトリーからの相対パスに変換する例。

	File dir = new File("C:\\temp\\html");
	File f   = new File("C:\\temp\\html\\abc\\index.html");

	URI fru = dir.toURI().relativize(f.toURI());
	File rf = new File(fru.toString());

	System.out.println("相対パスのFile:" + rf);
	System.out.println(rf.isAbsolute());

相対パスのFile:abc\index.html
false

ちなみにFileで相対パスから絶対パスにしたい場合、URIを使うまでもなく、new File(dir, rf.getPath())でよい。
(相対パスに含まれる「..」とかを除去したい場合は、さらにFile#getCanonicalFile()を呼び出すとか)


ローカルファイルの絶対パスからhttpのURIに変換する例

C:\temp\html」の下にある「abc\index.html」を、ベースURI「http://host/root/」を基準とした「http://host/root/abc/index.html」に変換する例。

	File dir = new File("C:\\temp\\html");
	File f   = new File("C:\\temp\\html\\abc\\index.html");

	URI fru = dir.toURI().relativize(f.toURI());
	System.out.println("ファイルの相対パスのURI:" + fru);

	URI base = new URI("http://host/root/"); //ベースURI
	URI uri = base.resolve(fru);
	System.out.println(uri);

ファイルの相対パスのURI:abc/index.html
http://host/root/abc/index.html

Fileのパスは相対パスでも大丈夫。(normalize()されるようだ)


Java目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま