Android的:如何parsingURLstring与空间URI对象?
我有一个string表示一个包含空格的URL,并希望将其转换为一个URI对象。 如果是简单的尝试做
String myString = "http://myhost.com/media/mp3s/9/Agenda of swine - 13. Persecution Ascension_ leave nothing standing.mp3"; URI myUri = new URI(myString);
它给了我
java.net.URISyntaxException: Illegal character in path at index X
其中索引X
是URLstring中第一个空格的位置。
我如何parsingmyString
到一个URI
对象?
实际上,您应该对 “无效”字符进行URI编码 。 由于string实际上包含完整的URL,因此很难对其进行正确的URI编码。 你不知道哪些斜杠/
应该被考虑,哪些不是。 事先不能预测原始String
。 这个问题真的需要在更高的层面上解决。 那个String
从哪里来? 它是硬编码的吗? 然后就相应地改变它自己。 它是否以用户input的forms出现? validation并显示错误,让用户自行解决。
无论如何,如果你可以确保只有 URL中的空格使得它无效,那么你也可以用%20
replacestring:
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
是不适合的任务,因为它被devise为按照application/x-www-form-urlencoded
规则(如在HTML表单中使用的那样)对查询string参数名称/值进行编码。 查看查询string参数的Java URL编码 。
java.net.URLEncoder.encode(finalPartOfString, "utf-8");
这将对string进行URL编码 。
finalPartOfString
是最后一个斜杠后的部分 – 在你的情况下,歌曲的名字,就像它看起来一样。
要处理URLpath中任意位置的空格,@和其他不安全字符,请使用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(); }
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(); }
我写了这个函数:
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; }