スペースを含むURLを表す文字列があり、それをURIオブジェクトに変換したい。単にそれを作成しようとすると
String myString = "http://myhost.com/media/File Name that has spaces inside.mp3";
URI myUri = new URI(myString);
それは私に与えます
Java.net.URISyntaxException: Illegal character in path at index X
ここで、インデックスX
は、URL文字列の最初のスペースの位置です。
myString
をURI
オブジェクトに解析するにはどうすればよいですか?
実際には、 RI-encode 「無効な」文字である必要があります。文字列には実際には完全なURLが含まれているため、適切にURIエンコードすることは困難です。どのスラッシュ/
を考慮する必要があるか、またどのスラッシュを考慮しないかはわかりません。事前にString
でそれを予測することはできません。問題は本当に高いレベルで解決する必要があります。 String
はどこから来たのですか?ハードコーディングされていますか?それに応じて自分で変更してください。ユーザー入力として入っていますか?検証してエラーを表示し、ユーザーが自分で解決できるようにします。
いずれにしても、それが無効になるURLのスペースがonlyだけであることを確認できる場合は、string-by-文字列を%20
に置き換えます:
URI uri = new URI(string.replace(" ", "%20"));
または、URIエンコードが必要な最後のスラッシュの後の部分のみであることを確認できる場合は、次の方法でそれを行うこともできます。 Android.net.Uri
ユーティリティクラス:
int pos = string.lastIndexOf('/') + 1;
URI uri = new URI(string.substring(0, pos) + Uri.encode(string.substring(pos)));
URLEncoder
は、application/x-www-form-urlencoded
ルール(HTMLフォームで使用)に従ってクエリ文字列パラメーターの名前/値をエンコードするように設計されているため、タスクに適していません。 クエリ文字列パラメーターのJava URLエンコード も参照してください。
Java.net.URLEncoder.encode(finalPartOfString, "utf-8");
これは RL-encode 文字列です。
finalPartOfString
は最後のスラッシュの後の部分です-あなたの場合は、曲の名前です。
URL url = Test.class.getResource(args[0]); // reading demo file path from
// same location where class
File input=null;
try {
input = new File(url.toURI());
} catch (URISyntaxException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
URLパス内の任意の場所にあるスペース、@、その他の安全でない文字を処理するには、Uri.BuilderをURLのローカルインスタンスと組み合わせて使用します here :
private Uri.Builder builder;
public Uri getUriFromUrl(String thisUrl) {
URL url = new URL(thisUrl);
builder = new Uri.Builder()
.scheme(url.getProtocol())
.authority(url.getAuthority())
.appendPath(url.getPath());
return builder.build();
}
この関数を書きました:
public static String encode(@NonNull String uriString) {
if (TextUtils.isEmpty(uriString)) {
Assert.fail("Uri string cannot be empty!");
return uriString;
}
// getQueryParameterNames is not exist then cannot iterate on queries
if (Build.VERSION.SDK_INT < 11) {
return uriString;
}
// Check if uri has valid characters
// See https://tools.ietf.org/html/rfc3986
Pattern allowedUrlCharacters = Pattern.compile("([A-Za-z0-9_.~:/?\\#\\[\\]@!$&'()*+,;" +
"=-]|%[0-9a-fA-F]{2})+");
Matcher matcher = allowedUrlCharacters.matcher(uriString);
String validUri = null;
if (matcher.find()) {
validUri = matcher.group();
}
if (TextUtils.isEmpty(validUri) || uriString.length() == validUri.length()) {
return uriString;
}
// The uriString is not encoded. Then recreate the uri and encode it this time
Uri uri = Uri.parse(uriString);
Uri.Builder uriBuilder = new Uri.Builder()
.scheme(uri.getScheme())
.authority(uri.getAuthority());
for (String path : uri.getPathSegments()) {
uriBuilder.appendPath(path);
}
for (String key : uri.getQueryParameterNames()) {
uriBuilder.appendQueryParameter(key, uri.getQueryParameter(key));
}
String correctUrl = uriBuilder.build().toString();
return correctUrl;
}