web-dev-qa-db-fra.com

URLEncoder incapable de traduire le caractère d'espace

Je m'attends à

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

à la sortie:

Hello%20World

(20 est ASCII code hexadécimal pour l'espace)

Cependant, ce que je reçois est:

Hello+World

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

153
Cheok Yan Cheng

Cela se comporte comme prévu. URLEncoder implémente les spécifications HTML pour coder les URL dans les formulaires HTML.

Depuis le javadocs :

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

et à partir de la spécification HTML :

application/x-www-form-urlencoded 

Formulaires soumis avec ce type de contenu doit être codé comme suit:

  1. Les noms de contrôle et les valeurs sont échappés. Les espaces sont remplacés par `+ '

Vous devrez le remplacer, par exemple:

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

Un espace est codé en %20 dans les URL et en + dans les données soumises par formulaire (type de contenu application/x-www-form-urlencoded). Vous avez besoin de l'ancien.

Utiliser 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 que coder l'espace. Utilisez plutôt une bibliothèque.

40
pyb

Cette classe effectue le codage de type application/x-www-form-urlencoded- plutôt que le codage en pourcentage. Par conséquent, remplacer par + correspond à un comportement correct. 

De javadoc:

Lors du codage d'une chaîne, 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 d'espace "" est converti en un signe plus "+". 
  • Tous les autres caractères sont dangereux et sont d'abord convertis en un ou plusieurs octets à l'aide d'un schéma de codage. Ensuite, chaque octet est représenté par la chaîne de 3 caractères "% xy", où xy est la représentation hexadécimale à deux chiffres de l'octet. Le schéma de codage recommandé est UTF-8. Cependant, pour des raisons de compatibilité, si aucun codage n'est spécifié, le codage par défaut de la plate-forme est utilisé. 
25
axtavt

Encoder les paramètres de requête

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

OU si vous voulez échapper des 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;
 }
13
fmucar

Hello+World indique comment un navigateur encodera les données de formulaire (application/x-www-form-urlencoded) pour une requête GET. Il s'agit du formulaire généralement accepté 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. Généralement, le seul problème est que l'encodage ne correspond pas.

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

Il serait généralement incorrect d'utiliser ce codage pour d'autres parties de l'URI (le chemin par exemple). Dans ce cas, vous devez utiliser le schéma de codage décrit dans RFC 3986 .

http://Host/Hello%20World

Plus ici .

11
McDowell

"+" est correct. Si vous avez vraiment besoin de% 20, remplacez ensuite les Plus vous-même.

4
Daniel

Je viens juste de me débattre avec cela aussi sur Android, j'ai réussi à tomber sur Uri.encode (String, String) alors que spécifique à Android (Android.net.Uri) pourrait être utile à certains. 

static String encode (String s, Chaîne autorisée)

https://developer.Android.com/reference/Android/net/Uri.html#encode(Java.lang.String, Java.lang.String)

2
Chrispix

Cela a fonctionné pour moi

org.Apache.catalina.util.URLEncoder ul = new org.Apache.catalina.util.URLEncoder().encode("MY URL");
1
Hitesh Kumar

Bien que très vieux, néanmoins une réponse rapide: 

Spring fournit UriUtils - avec cela, vous pouvez spécifier comment encoder et quelle partie est liée à un URI, par exemple.

encodePathSegment
encodePort
encodeFragment
encodeUriVariables
....

Je les utilise parce que nous utilisons déjà Spring, c’est-à-dire qu’aucune bibliothèque supplémentaire n’est requise!

0
LeO

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

Oui, cette méthode Java.net.URLEncoder.encode n'était pas faite pour convertir "" en "20%" selon la spécification ( source ). 

Le caractère d'espace "" est converti en un signe plus "+".

Même si ce n’est pas la bonne méthode, vous pouvez le modifier comme suit: System.out.println(Java.net.URLEncoder.encode("Hello World", "UTF-8").replaceAll("\\+", "%20"));have a Nice day =).

0
Pregunton

Découvrez la classe Java.net.URI.

0
Fredrik Widerberg