218 votes

URLEncoder ne parvient pas à traduire le caractère espace

Je m'attends à ce que

System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8"));

à la sortie :

Hello%20World

(20 est le code ASCII Hex pour l'espace)

Cependant, ce que je reçois est :

Hello+World

Est-ce que j'utilise la mauvaise méthode ? Quelle est la méthode correcte que je devrais utiliser ?

3 votes

Le nom de la classe est en effet déroutant, et beaucoup de gens l'ont utilisé à tort. Cependant, ils ne le remarquent pas, car lorsque URLDecoder est appliqué, la valeur originale est restaurée, donc + ou %20 n'a pas vraiment d'importance pour eux.

243voto

dogbane Points 85749

Cela se comporte comme prévu. Le site URLEncoder met en œuvre les spécifications HTML sur la manière d'encoder les URL dans les formulaires HTML.

De la javadocs :

Cette classe contient des méthodes statiques pour convertir une chaîne de caractères au format application/x-www-form-urlencoded MIME en application/x-www-form-urlencoded.

et de la Spécification HTML :

application/x-www-form-urlencoded

Formulaires soumis avec ce type de contenu doivent être encodés comme suit :

  1. Les noms et les valeurs des contrôles sont échappés. Les caractères d'espacement sont remplacés par `+'.

Vous devrez le remplacer, par exemple :

System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replace("+", "%20"));

21 votes

Eh bien, c'est une réponse en effet, plutôt que de remplacer n'y a-t-il pas une bibliothèque java ou une fonction pour effectuer la tâche / ?

5 votes

Le signe plus doit être échappé t.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replace("\\+", "%20"));

28 votes

@congliu c'est incorrect - vous pensez probablement à replaceAll() qui fonctionne avec les regex - replace() est un simple remplacement de séquence de caractères.

71voto

pyb Points 2223

Un espace est codé pour %20 dans les URLs, et à + dans les données soumises par les formulaires (type de contenu application/x-www-form-urlencoded). Vous avez besoin du premier.

Utilisation de Goyave :

dependencies {
     compile 'com.google.guava:guava:23.0'
     // or, for Android:
     compile 'com.google.guava:guava:23.0-android'
}

Vous pouvez utiliser UrlEscapers :

String encodedString = UrlEscapers.urlFragmentEscaper().escape(inputString);

N'utilisez pas String.replace, cela ne ferait qu'encoder l'espace. Utilisez une bibliothèque à la place.

26voto

axtavt Points 126632

Cette classe effectue application/x-www-form-urlencoded -plutôt qu'un codage en pourcentage, remplaçant ainsi le code con + est un comportement correct.

De la javadoc :

Lors du codage d'une chaîne de caractères, les règles suivantes s'appliquent :

  • Les caractères alphanumériques "a" à "z", "A" à "Z" et "0" à "9" restent les mêmes.
  • Les caractères spéciaux ".", "-", "*" et "_" restent les mêmes.
  • Le caractère espace " " est converti en un signe plus "+".
  • Tous les autres caractères ne sont pas sûrs et sont d'abord convertis en un ou plusieurs octets en utilisant un schéma de codage. Chaque octet est ensuite représenté par la chaîne de trois caractères "%xy", où xy est la représentation hexadécimale à deux chiffres de l'octet. Le schéma d'encodage recommandé est UTF-8. Toutefois, pour des raisons de compatibilité, si aucun codage n'est spécifié, c'est le codage par défaut de la plate-forme qui est utilisé.

23voto

fmucar Points 6937

Encoder les paramètres de la requête

org.apache.commons.httpclient.util.URIUtil
    URIUtil.encodeQuery(input);

OU si vous voulez échapper les caractères dans l'URI

public static String escapeURIPathParam(String input) {
  StringBuilder resultStr = new StringBuilder();
  for (char ch : input.toCharArray()) {
   if (isUnsafe(ch)) {
    resultStr.append('%');
    resultStr.append(toHex(ch / 16));
    resultStr.append(toHex(ch % 16));
   } else{
    resultStr.append(ch);
   }
  }
  return resultStr.toString();
 }

 private static char toHex(int ch) {
  return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10);
 }

 private static boolean isUnsafe(char ch) {
  if (ch > 128 || ch < 0)
   return true;
  return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0;
 }

5 votes

Utilisation de org.apache.commons.httpclient.util.URIUtil semble être le moyen le plus efficace de résoudre le problème !

1 votes

URIUtil semble avoir disparu dans les versions actuelles, y a-t-il des alternatives ?

11voto

McDowell Points 62645

Hello+World est la façon dont un navigateur codera les données du formulaire ( application/x-www-form-urlencoded ) pour un GET et c'est la forme généralement acceptée pour la partie "requête" d'un URI.

http://host/path/?message=Hello+World

Si vous envoyez cette demande à un servlet Java, celui-ci décodera correctement la valeur du paramètre. En général, le seul cas où il y a des problèmes est celui où l'encodage ne correspond pas.

À proprement parler, rien dans les spécifications HTTP ou URI n'exige que la partie requête soit codée à l'aide de l'algorithme d'encodage de l'URI. application/x-www-form-urlencoded paires clé-valeur ; la partie "requête" doit simplement être sous la forme acceptée par le serveur web. En pratique, il est peu probable que cela pose un problème.

Il serait généralement incorrect d'utiliser cet encodage pour d'autres parties de l'URI (le chemin d'accès par exemple). Dans ce cas, vous devriez utiliser le schéma d'encodage tel que décrit dans le document suivant RFC 3986 .

http://host/Hello%20World

Plus de aquí .

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