Javaを使用して、フラグメント識別子を取り除き、さまざまなURIセットの単純な正規化(小文字のスキーム、ホストなど)を実行したいと思います。入力URIと出力URIは、一般的なHTTPの意味で同等である必要があります。
通常、これは簡単なはずです。http://blah.org/A_%28Secret%29.xml#blah
ただし、パーセントでエンコードされるのようなURIの場合(Secret)
、の動作java.util.URI
は生活を困難にします。
正規化メソッドはhttp://blah.org/A_%28Secret%29.xml
URIから戻る必要があり、解釈において同等ではhttp://blah.org/A_%28Secret%29.xml
ありhttp://blah.org/A_(Secret).xml
ません[§2.2; RFC3968 ]
したがって、次の2つの正規化方法があります。
URI u = new URI("http://blah.org/A_%28Secret%29.xml#blah");
System.out.println(u);
// prints "http://blah.org/A_%28Secret%29.xml#blah"
String path1 = u.getPath(); //gives "A_(Secret).xml"
String path2 = u.getRawPath(); //gives "A_%28Secret%29.xml"
//NORMALISE METHOD 1
URI norm1 = new URI(u.getScheme().toLowerCase(), u.getUserInfo(),
u.getHost().toLowerCase(), u.getPort(), path1,
u.getQuery(), null);
System.out.println(norm1);
// prints "http://blah.org/A_(Secret).xml"
//NORMALISE METHOD 2
URI norm2 = new URI(u.getScheme().toLowerCase(), u.getUserInfo(),
u.getHost().toLowerCase(), u.getPort(), path2,
u.getQuery(), null);
System.out.println(norm2);
// prints "http://blah.org/A_%2528Secret%2529.xml"
ご覧のとおり、URIは解析され、フラグメント識別子なしで再構築されます。
ただし、メソッド1の場合、u.getPath()
エンコードされていないURIが返され、最終的なURIが変更されます。
メソッド2の場合u.getRawPath()
、元のパスを返しますが、コンストラクターに渡されるとURI
、Javaはダブルエンコーディングを追加することを決定します。
これは、中国のフィンガートラップのように感じます。
したがって、2つの主な質問:
- なぜ
java.util.URI
エンコーディングで遊ぶ必要性を感じるのですか? - 元のパーセントエンコーディングをいじることなく、この正規化メソッドをどのように実装できますか?
(私はむしろ、java.util.URI
自明ではないの解析/連結メソッドを実装する必要はありません。)
編集:ここにURI
javadocからのいくつかのさらなる情報があります。
単一引数のコンストラクターでは、引数に不正な文字を引用符で囲む必要があり、エスケープされたオクテットやその他の存在する文字を保持します。
複数引数のコンストラクターは、それらが表示されるコンポーネントで必要とされるように、不正な文字を引用します。パーセント文字('%')は、これらのコンストラクターによって常に引用符で囲まれます。その他の文字はすべて保持されます。
getRawUserInfo、getRawPath、getRawQuery、getRawFragment、getRawAuthority、およびgetRawSchemeSpecificPartメソッドは、エスケープされたオクテットを解釈せずに、対応するコンポーネントの値を生の形式で返します。これらのメソッドによって返される文字列には、エスケープされたオクテットと他の文字の両方が含まれている可能性があり、不正な文字は含まれていません。
getUserInfo、getPath、getQuery、getFragment、getAuthority、およびgetSchemeSpecificPartメソッドは、対応するコンポーネント内のエスケープされたオクテットをデコードします。これらのメソッドによって返される文字列には、他の文字と不正な文字の両方が含まれている可能性があり、エスケープされたオクテットは含まれません。
toStringメソッドは、必要なすべての引用符を含むURI文字列を返しますが、他の文字が含まれている場合があります。
toASCIIStringメソッドは、他の文字を含まない、完全に引用符で囲まれ、エンコードされたURI文字列を返します。
URI
そのため、クラスによって内部的にURLエンコードが混乱することなく、マルチ引数コンストラクターを使用することはできません。パー!