我有一个表示包含空格的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
其中index X
是URL字符串中第一个空格的位置。
如何将myString
解析为URI
个对象?
答案 0 :(得分:120)
您实际上应该URI-encode“无效”字符。由于字符串实际上包含完整的URL,因此很难对其进行正确的URI编码。您不知道应该考虑哪些斜杠/
,哪些不应该考虑。{1}}。您无法事先预测原始String
。问题确实需要在更高层次上解决。 String
来自哪里?它是硬编码的吗?然后相应地自己更改。它是否以用户输入的形式出现?验证它并显示错误,让用户自行解决。
无论如何,如果您可以确保仅 URL中的空格使其无效,那么您也可以使用%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 encoding of query string parameters。
答案 1 :(得分:19)
java.net.URLEncoder.encode(finalPartOfString, "utf-8");
这将是URL-encode字符串。
finalPartOfString
是最后一次斜线之后的部分 - 就你的情况而言,就是这首歌的名字。
答案 2 :(得分:2)
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();
}
答案 3 :(得分:1)
要处理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();
}
答案 4 :(得分:0)
我写了这个函数:
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;
}