Encodage d'URL dans Android

336

Comment encodez-vous une 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://in urlAsStringest remplacé par http%3A%2F%2Fin encodedURLpuis j'obtiens un java.net.MalformedURLExceptionlorsque j'utilise l'URL.

hpique
la source

Réponses:

630

Vous n'encodez pas l'URL entière, seulement certaines parties qui proviennent de "sources non fiables".

String query = URLEncoder.encode("apples oranges", "utf-8");
String 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();
yanchenko
la source
1
Que faire si l'URL entière n'est pas fiable? Dois-je tout encoder sauf le protocole? Je m'attendais en quelque sorte à une méthode pratique pour le faire.
hpique
5
Ensuite, c'est juste une URL cassée. L'idée est d'empêcher la partie requête de casser l'url.
yanchenko
5
@hgpc - jetez un œil à la section 3 de la RFC3986 ( tools.ietf.org/html/rfc3986#section-3 ). Il vous indique comment coder les différentes parties d'un URI. Malheureusement, chaque partie de l'URI (hôte, chemin, requête, etc.) a des règles de codage légèrement différentes.
D.Shawley
2
C'est très bien dans la mesure où vous traitez simplement une partie spécifique d'une URL et vous savez comment construire ou reconstruire l'URL. Pour une approche plus générale qui peut gérer n'importe quelle chaîne d'URL, voir ma réponse ci-dessous.
Craig B
8
Pourquoi est-ce que j'obtiens un avertissement de dépréciation en utilisant ceci? Utilisé à la Uri.encode(query);place.
prasanthv
166

Je vais ajouter une suggestion ici. Vous pouvez le faire, ce 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 encodés afin de pouvoir l'utiliser pour une demande.

Cela profite de quelques fonctionnalités disponibles dans les classes Android. Tout d'abord, la classe URL peut décomposer une URL en ses composants appropriés, il n'est donc pas nécessaire que vous effectuiez un travail de recherche / remplacement de chaîne. Deuxièmement, cette approche tire parti de la fonctionnalité de classe URI consistant à é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 vous-même.

Craig B
la source
19
Ce devrait être la bonne réponse. c'est la manière formelle et claire de le faire
Asanka Senavirathna
3
Il peut également être judicieux d'urldécoder urlStr avant de l'envoyer au constructeur d'URL. URLDecoder.decode (urlStr)
Jakob Eriksson
1
Merci pour le post :) Mais je suis confronté à un problème. Si l'URL est déjà partiellement codée, elle code les parties déjà codées. Que devrais-je faire? Par exemple: dj-videos.us/Music/XclusiveSinGleTrack/320%20Kbps/… Le% 20 est codé à% 2520
berserk
2
@berserk S'il est déjà codé, ne le codez pas. Vous ne devriez pas entrer dans un état où il est partiellement encodé, ou vous ne savez pas s'il est ou non encodé.
Marquis de Lorne
3
Cette méthode ne code pas les caractères tels que ğ en% C4% 9F. Accepté on encode!
Alexander Prokofyev,
74

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

Encode les caractères de la chaîne donnée sous la forme «%» - octets d'échappement à l'aide du schéma UTF-8. Laisse les lettres ("AZ", "az"), les chiffres ("0-9") et les caractères non réservés ("_- !. ~ '() *") intacts. Encode tous les autres personnages.

Ex/

String urlEncoded = "http://stackoverflow.com/search?q=" + Uri.encode(query);
tanutapi
la source
2
Malheureusement Uri.encode("a=1&b=1")produit a%3D1%26b%3D1mais attendua=1&b=1
loentar
14
@loentar C'est le résultat attendu. Si l'utilisateur entre en a=1&b=1tant que requête, vous souhaitez interroger exactement cela.
Anubian Noob
Quelle différence avec URLEncoder.encode (StringHere, "UTF-8")
stuckedoverflow
@stuckedoverflow D'une part, Uri.encode (str) ne lève pas d'exception vérifiée contrairement à URLEncoder.encode (str, "UTF-8")
deekshith
50

Vous pouvez également l'utiliser

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

c'est la méthode la plus simple

Jedo
la source
1
ce n'est pas la meilleure solution, mais c'est définitivement une bonne solution rapide ... merci
Sebastian Breit
4
Il s'agit de la solution la plus rapide lorsque l'URL entière n'est pas fiable. Merci!
user1032613
Êtes-vous sûr que le% devrait être autorisé? Ne devrait-il pas être encodé?
MediumOne
1
Comment encoder cette URL pour pouvoir la partager et ensuite l'utilisateur peut ouvrir le lien et voir la page: yazd20.com//News/2015/11/ استند-آب-كمدي-حسن-ريوندي-در-يزد. Html
Ahmad Ebrahimi
3
try {
                    query = URLEncoder.encode(query, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
Joolah
la source
1

vous pouvez utiliser les méthodes ci-dessous

public static String parseUrl(String surl) throws Exception
{
    URL u = new URL(surl);
    return new URI(u.getProtocol(), u.getAuthority(), u.getPath(), u.getQuery(), u.getRef()).toString();
}

ou

public String parseURL(String url, Map<String, String> params)
{
    Builder builder = Uri.parse(url).buildUpon();
    for (String key : params.keySet())
    {
        builder.appendQueryParameter(key, params.get(key));
    }
    return builder.build().toString();
}

le second est meilleur que le premier.

Elango
la source
0

Trouvez des caractères arabes et remplacez-les par son encodage UTF-8. quelque chose comme ça:

for (int i = 0; i < urlAsString.length(); i++) {
    if (urlAsString.charAt(i) > 255) {
        urlAsString = urlAsString.substring(0, i) + URLEncoder.encode(urlAsString.charAt(i)+"", "UTF-8") + urlAsString.substring(i+1);
    }
}
encodedURL = urlAsString;
Ali Jafari
la source