Android: Comment analyser la chaîne D'URL avec les espaces de L'objet URI?

j'ai une chaîne représentant une URL contenant des espaces et je veux la convertir à un objet URI. Si est simple, essayez de faire des

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

il me donne

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

où l'index X est la position du premier espace dans la chaîne D'URL.

Comment puis-je analyser myString en un objet URI ?

60
demandé sur Cœur 2010-04-07 18:21:28

5 réponses

vous devriez en fait URI-encoder les caractères" invalides". Comme la chaîne contient en fait L'URL complète, il est difficile de L'URI-encoder correctement. Vous ne savez pas quels slashs / doivent être pris en compte et lesquels Non. Vous ne pouvez pas prédire cela sur un raw String à l'avance. Le problème doit être résolu à un niveau supérieur. D'où vient ce String ? Est-il figé? Alors changez-le vous-même en conséquence. Faire venez en tant que saisie de l'utilisateur? Valider et afficher l'erreur, laisser l'utilisateur se résoudre lui-même.

de toute façon, si vous pouvez vous assurer que ce sont seulement les espaces dans les URLs qui le rendent invalide, alors vous pouvez aussi juste faire un remplacement chaîne par chaîne avec %20 :

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

Ou si vous pouvez vous assurer que c'est seulement la partie après le dernier slash qui doit être URI codé, alors vous pouvez aussi le faire avec aide de android.net.Uri classe d'utilité:

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

Ne remarque que URLEncoder est insuitable pour la tâche car il est conçu pour encoder paramètre de chaîne de requête noms/valeurs par application/x-www-form-urlencoded règles (comme utilisé dans les formulaires HTML). Voir aussi Java URL encodage des paramètres de chaîne de requête .

117
répondu BalusC 2017-05-23 12:02:48
java.net.URLEncoder.encode(finalPartOfString, "utf-8");

ce sera URL-Encoder la chaîne de caractères.

finalPartOfString est la partie après le dernier slash - dans votre cas, le nom de la chanson, comme il semble.

20
répondu Bozho 2010-04-07 14:29:43

pour gérer les espaces, @, et autres caractères dangereux dans des emplacements arbitraires dans le chemin d'url, utilisez Uri.Builder en combinaison avec une instance locale D'URL comme j'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();
}
2
répondu Phileo99 2017-05-23 10:31:02
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
répondu siddmuk2005 2014-07-04 19:03:49

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
répondu hadilq 2016-07-18 08:24:53