J’ai une chaîne représentant une URL contenant des espaces et je souhaite la convertir en object URI. Si c’est simple, essayez de faire
Ssortingng mySsortingng = "http://myhost.com/media/mp3s/9/Agenda of swine - 13. Persecution Ascension_ leave nothing standing.mp3"; URI myUri = new URI(mySsortingng);
ça me donne
java.net.URISyntaxException: Illegal character in path at index X
où index X
est la position du premier espace dans la chaîne URL.
Comment puis-je parsingr mySsortingng
dans un object URI
?
En fait, vous devez encoder les caractères “invalides” par URI . Comme la chaîne contient l’URL complète, il est difficile de la coder correctement. Vous ne savez pas quelles barres obliques /
doivent être sockets en compte et lesquelles non. Vous ne pouvez pas prédire cela sur une Ssortingng
brute au préalable. Le problème doit vraiment être résolu à un niveau supérieur. D’où vient cette Ssortingng
? Est-ce que c’est codé en dur? Puis changez-le vous-même en conséquence. Est-ce qu’il entre en tant que saisie utilisateur? Validez-le et affichez l’erreur, laissez l’utilisateur se résoudre.
À tout moment, si vous pouvez vous assurer que ce ne sont que des espaces dans les URL qui le rendent invalide, alors vous pouvez également faire un remplacement chaîne par chaîne avec %20
:
URI uri = new URI(ssortingng.replace(" ", "%20"));
Ou si vous pouvez vous assurer que ce n’est que la partie après la dernière barre oblique qui doit être encodée en URI, alors vous pouvez aussi le faire avec l’aide de la classe utilitaire android.net.Uri
:
int pos = ssortingng.lastIndexOf('/') + 1; URI uri = new URI(ssortingng.subssortingng(0, pos) + Uri.encode(ssortingng.subssortingng(pos)));
Notez que URLEncoder
est inadapté à la tâche car il est conçu pour encoder les noms / valeurs de parameters de chaîne de requête conformément aux règles d’ application/x-www-form-urlencoded
(utilisées dans les formulaires HTML). Voir aussi le codage URL Java des parameters de chaîne de requête .
java.net.URLEncoder.encode(finalPartOfSsortingng, "utf-8");
Cela va encoder la chaîne en URL .
finalPartOfSsortingng
est la partie après la dernière barre oblique – dans votre cas, le nom de la chanson, comme il semble.
Pour gérer les espaces, @ et autres caractères non sécurisés à des emplacements arbitraires du chemin d’URL, utilisez Uri.Builder en combinaison avec une instance locale d’URL, comme je l’ai décrit ici :
private Uri.Builder builder; public Uri getUriFromUrl(Ssortingng 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(); }
J’ai écrit cette fonction:
public static Ssortingng encode(@NonNull Ssortingng uriSsortingng) { if (TextUtils.isEmpty(uriSsortingng)) { Assert.fail("Uri ssortingng cannot be empty!"); return uriSsortingng; } // 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; }