Java Android:如何将带有空格的 URL 字符串解析为 URI 对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2593214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: how to parse URL String with spaces to URI object?
提问by whlk
I have a string representing an URL containing spaces and want to convert it to an URI object. If I simply try to create it via
我有一个表示包含空格的 URL 的字符串,并希望将其转换为 URI 对象。如果我只是尝试通过创建它
String myString = "http://myhost.com/media/File Name that has spaces inside.mp3";
URI myUri = new URI(myString);
it gives me
它给了我
java.net.URISyntaxException: Illegal character in path at index X
where index X
is the position of the first space in the URL string.
其中 indexX
是 URL 字符串中第一个空格的位置。
How can i parse myString
into a URI
object?
我怎样才能解析myString
成一个URI
对象?
采纳答案by BalusC
You should in fact URI-encodethe "invalid" characters. Since the string actually contains the complete URL, it's hard to properly URI-encode it. You don't know which slashes /
should be taken into account and which not. You cannot predict that on a raw String
beforehand. The problem really needs to be solved at a higher level. Where does that String
come from? Is it hardcoded? Then just change it yourself accordingly. Does it come in as user input? Validate it and show error, let the user solve itself.
实际上,您应该对“无效”字符进行 URI 编码。由于字符串实际上包含完整的 URL,因此很难对其进行正确的 URI 编码。您不知道/
应该考虑哪些斜线,哪些不应该考虑。您无法String
事先预测原始数据。这个问题确实需要在更高的层次上解决。这是String
从哪里来的?它是硬编码的吗?然后自己相应地改变它。它是作为用户输入进来的吗?验证并显示错误,让用户自行解决。
At any way, if you can ensure that it are onlythe spaces in URLs which makes it invalid, then you can also just do a string-by-string replace with %20
:
无论如何,如果您可以确保只有URL 中的空格使其无效,那么您也可以使用%20
以下内容逐个字符串替换:
URI uri = new URI(string.replace(" ", "%20"));
Or if you can ensure that it's onlythe part after the last slash which needs to be URI-encoded, then you can also just do so with help of android.net.Uri
utility class:
或者,如果您可以确保它只是需要进行 URI 编码的最后一个斜杠之后的部分,那么您也可以在android.net.Uri
实用程序类的帮助下这样做:
int pos = string.lastIndexOf('/') + 1;
URI uri = new URI(string.substring(0, pos) + Uri.encode(string.substring(pos)));
Do note that URLEncoder
is insuitable for the task as it's designed to encode query string parameter names/values as per application/x-www-form-urlencoded
rules (as used in HTML forms). See also Java URL encoding of query string parameters.
请注意,这URLEncoder
不适合该任务,因为它旨在根据application/x-www-form-urlencoded
规则(如在 HTML 表单中使用)对查询字符串参数名称/值进行编码。另请参阅查询字符串参数的 Java URL 编码。
回答by Bozho
java.net.URLEncoder.encode(finalPartOfString, "utf-8");
This will URL-encodethe string.
这将对字符串进行 URL 编码。
finalPartOfString
is the part after the last slash - in your case, the name of the song, as it seems.
finalPartOfString
是最后一个斜杠之后的部分 - 在你的情况下,这首歌的名字,看起来。
回答by Phileo99
To handle spaces, @, and other unsafe characters in arbitrary locations in the url path, Use Uri.Builder in combination with a local instance of URL as I have described here:
要处理 url 路径中任意位置的空格、@ 和其他不安全字符,请将 Uri.Builder 与本地 URL 实例结合使用,如我在此处所述:
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();
}
回答by siddmuk2005
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();
}
回答by hadilq
I wrote this function:
我写了这个函数:
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;
}