381 votes

Codage des URL dans Android

Comment coder un URL dans Android ?

Je pensais que c'était comme ça :

final String encodedURL = URLEncoder.encode(urlAsString, "UTF-8");
URL url = new URL(encodedURL);

Si je fais ce qui précède, le http:// sur urlAsString est remplacé par http%3A%2F%2F sur encodedURL et ensuite j'obtiens un java.net.MalformedURLException lorsque j'utilise l'URL.

696voto

yanchenko Points 24142

Vous ne codez pas l'intégralité de l'URL, mais seulement les parties qui proviennent de "sources non fiables".

  • Java :

    String query = URLEncoder.encode("apples oranges", "utf-8");
    String url = "http://stackoverflow.com/search?q=" + query;
  • Kotlin :

    val query: String = URLEncoder.encode("apples oranges", "utf-8")
    val url = "http://stackoverflow.com/search?q=$query"

Alternativement, vous pouvez utiliser Strings.urlEncode(String str) de DroidParts qui ne lève pas d'exceptions vérifiées.

Ou utilisez quelque chose comme

String uri = Uri.parse("http://...")
                .buildUpon()
                .appendQueryParameter("key", "val")
                .build().toString();

1 votes

Que faire si l'url entière n'est pas fiable ? Devrais-je tout coder sauf le protocole ? Je m'attendais à ce qu'il existe une méthode pratique pour faire cela.

5 votes

Dans ce cas, il s'agit simplement d'une url cassée. L'idée est d'empêcher la partie requête de casser l'url.

6 votes

@hgpc - regardez la section 3 du RFC3986 ( tools.ietf.org/html/rfc3986#section-3 ). Il vous indique comment encoder les différentes parties d'un URI. Malheureusement, chaque partie de l'URI (hôte, chemin, requête, etc.) a des règles d'encodage légèrement différentes.

172voto

Craig B Points 2373

Je vais ajouter une suggestion ici. Vous pouvez faire ceci qui évite d'avoir à obtenir des bibliothèques externes.

Essayez ceci :

String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();

Vous pouvez voir que dans cette URL particulière, j'ai besoin d'avoir ces espaces codés pour pouvoir l'utiliser pour une requête.

Cela permet de tirer parti de quelques fonctionnalités disponibles dans les classes Android. Tout d'abord, la classe URL peut décomposer une URL en ses composants propres, ce qui vous évite d'avoir à effectuer un travail de recherche/remplacement de chaîne. Deuxièmement, cette approche tire profit de la classe URI qui permet d'échapper correctement les composants lorsque vous construisez un URI via des composants plutôt qu'à partir d'une seule chaîne.

La beauté de cette approche est que vous pouvez prendre n'importe quelle chaîne d'url valide et la faire fonctionner sans avoir besoin de connaissances particulières.

19 votes

Cela devrait être la bonne réponse. C'est la manière formelle et claire de procéder.

3 votes

Il peut également être judicieux de décoder urlStr avant de l'envoyer au constructeur d'URL. URLDecoder.decode(urlStr)

1 votes

Réponse exacte. Merci beaucoup. Vous avez fait ma journée.

85voto

tanutapi Points 241

Pour Android, j'utiliserais String Android.net.Uri.encode(String s)

Encode les caractères de la chaîne de caractères donnée sous forme d'octets mis en évidence par '%' en utilisant le schéma UTF-8. Laisse les lettres ("A-Z", "a-z"), les chiffres ("0-9") et les caractères non réservés ("_- !.~'()*") intacts. Encode tous les autres caractères.

Ex/

String urlEncoded = "http://stackoverflow.com/search?q=" + Uri.encode(query);

2 votes

Malheureusement Uri.encode("a=1&b=1") produit a%3D1%26b%3D1 mais attendu a=1&b=1

17 votes

@loentar C'est le résultat attendu. Si l'utilisateur entre a=1&b=1 comme une requête, vous voulez interroger exactement cela.

2 votes

Comment différent ceci avec URLEncoder.encode(StringHere, "UTF-8")

52voto

Jedo Points 101

Vous pouvez aussi utiliser ceci

private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%";
String urlEncoded = Uri.encode(path, ALLOWED_URI_CHARS);

c'est la méthode la plus simple

1 votes

Ce n'est pas la meilleure solution, mais c'est certainement une solution rapide et agréable... merci.

4 votes

C'est la solution la plus rapide lorsque l'ensemble de l'URL n'est pas fiable. Merci !

1 votes

Êtes-vous sûr que le % doit être autorisé ? Ne devrait-il pas être encodé ?

4voto

Joolah Points 4617
try {
                    query = URLEncoder.encode(query, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X