web-dev-qa-db-fra.com

Android: comment analyser une chaîne d'URL avec des espaces en objet URI?

J'ai une chaîne représentant une URL contenant des espaces et je souhaite la convertir en objet URI. Si est simple essayer de faire

String myString = "http://myhost.com/media/mp3s/9/Agenda of swine - 13. Persecution Ascension_ leave nothing standing.mp3";
URI myUri = new URI(myString);

ça me donne 

Java.net.URISyntaxException: Illegal character in path at index X

où index X est la position du premier espace de la chaîne d'URL.

Comment analyser myString dans un objet URI?

60
whlk

Vous devriez en fait URI-encoder les caractères "invalides". Étant donné que la chaîne contient en réalité l'URL complète, il est difficile de la coder correctement en URI. Vous ne savez pas quelles barres obliques / doivent être prises en compte et lesquelles ne le sont pas. Vous ne pouvez pas prédire cela sur une Stringsauve au préalable. Le problème doit vraiment être résolu à un niveau supérieur. D'où vient cette String? Est-ce codé en dur? Ensuite, changez-le vous-même en conséquence. Est-ce que cela entre en tant que saisie d'utilisateur? Validez-le et affichez l'erreur, laissez l'utilisateur se résoudre lui-même.

Quoi qu’il en soit, si vous pouvez vous assurer que c’est uniquement les espaces dans les URL qui le rend invalide, vous pouvez également effectuer un remplacement chaîne par chaîne par %20:

URI uri = new URI(string.replace(" ", "%20"));

Ou si vous pouvez vous assurer qu'il ne s'agit que de seulement de la partie après la dernière barre oblique qui doit être encodée en URI, vous pouvez également le faire simplement à l'aide de Android.net.Uri utility class

int pos = string.lastIndexOf('/') + 1;
URI uri = new URI(string.substring(0, pos) + Uri.encode(string.substring(pos)));

Notez que URLEncoder ne convient pas à la tâche car il est conçu pour coder les noms/valeurs de paramètres de chaîne de requête conformément aux règles application/x-www-form-urlencoded (telles qu'utilisées dans les formulaires HTML). Voir aussi Codage d'URL Java des paramètres de chaîne de requête .

119
BalusC
Java.net.URLEncoder.encode(finalPartOfString, "utf-8");

Ce sera URL-encoder la chaîne.

finalPartOfString est la partie après la dernière barre oblique - dans votre cas, le nom de la chanson, comme il semble.

19
Bozho
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();
}
2
siddmuk2005

Pour gérer les espaces, @ et d'autres caractères non sécurisés situés à des emplacements arbitraires dans le 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(String thisUrl) {
    URL url = new URL(thisUrl);
    builder =  new Uri.Builder()
                            .scheme(url.getProtocol())
                            .authority(url.getAuthority())
                            .appendPath(url.getPath());
    return builder.build();
}
1
Phileo99

J'ai écrit cette fonction:

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;
}
0
hadilq