web-dev-qa-db-de.com

URLEncoder kann kein Leerzeichen übersetzen

Ich erwarte

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

ausgeben:

Hello%20World

(20 ist ASCII Hex-Code für Leerzeichen)

Was ich jedoch bekomme ist:

Hello+World

Benutze ich die falsche Methode? Was ist die richtige Methode, die ich verwenden sollte?

153
Cheok Yan Cheng

Dies verhält sich wie erwartet. Die Variable URLEncoder implementiert die HTML-Spezifikationen zum Kodieren von URLs in HTML-Formularen.

Aus den javadocs :

Diese Klasse enthält statische Methoden für Konvertieren eines Strings in die application/x-www-form-urlencoded MIME Format.

und aus der HTML-Spezifikation :

application/x-www-form-urlencoded 

Mit diesem Inhaltstyp übermittelte Formulare muss wie folgt codiert sein:

  1. Steuerelementnamen und -werte werden mit Escapezeichen versehen. Leerzeichen werden ersetzt von "+"

Sie müssen es ersetzen, z.

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

Ein Leerzeichen wird in URLs zu %20 und in übermittelten Formularen zu + (Inhaltstyp application/x-www-form-urlencoded) codiert. Du brauchst den ersteren.

Verwenden von Guave :

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

Sie können UrlEscapers verwenden:

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

Verwenden Sie keine Zeichenfolge.replace, dies würde nur den Platz kodieren. Verwenden Sie stattdessen eine Bibliothek.

40
pyb

Diese Klasse führt eine Codierung mit application/x-www-form-urlencoded- anstelle einer Prozentcodierung durch. Daher ist es korrekt, durch + zu ersetzen. 

Von Javadoc:

Beim Codieren einer Zeichenfolge gelten folgende Regeln: 

  • Die alphanumerischen Zeichen "a" bis "z", "A" bis "Z" und "0" bis "9" bleiben gleich.
  • Die Sonderzeichen ".", "-", "*" und "_" bleiben gleich. 
  • Das Leerzeichen "" wird in ein Pluszeichen "+" umgewandelt. 
  • Alle anderen Zeichen sind unsicher und werden zuerst mithilfe eines Codierschemas in ein oder mehrere Bytes umgewandelt. Dann wird jedes Byte durch die 3-stellige Zeichenfolge "% xy" dargestellt, wobei xy die zweistellige hexadezimale Darstellung des Bytes ist. Das empfohlene Kodierungsschema ist UTF-8. Aus Kompatibilitätsgründen wird jedoch die Standardkodierung der Plattform verwendet, wenn keine Kodierung angegeben wird. 
25
axtavt

Abfragecodes codieren

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

ODER wenn Sie Zeichen innerhalb der URI vermeiden möchten

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 " %$&+,/:;[email protected]<>#%".indexOf(ch) >= 0;
 }
13
fmucar

Hello+World codiert ein Browser Formulardaten (application/x-www-form-urlencoded) für eine GET-Anforderung. Dies ist das allgemein akzeptierte Formular für den Abfrageteil eines URI.

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

Wenn Sie diese Anforderung an ein Java-Servlet gesendet haben, dekodiert das Servlet den Parameterwert korrekt. Normalerweise gibt es hier nur Probleme, wenn die Kodierung nicht übereinstimmt.

Genau genommen besteht in den HTTP- oder URI-Spezifikationen keine Anforderung, dass der Abfrageteil mit application/x-www-form-urlencoded-Schlüsselwertpaaren codiert werden muss. Der Abfrageteil muss nur in der Form vorliegen, die der Webserver akzeptiert. In der Praxis dürfte dies kein Problem sein.

Es wäre im Allgemeinen falsch, diese Kodierung für andere Teile des URI (beispielsweise den Pfad) zu verwenden. In diesem Fall sollten Sie das Kodierungsschema wie in RFC 3986 beschrieben verwenden.

http://Host/Hello%20World

Mehr hier .

11
McDowell

"+" ist richtig. Wenn Sie wirklich% 20 benötigen, tauschen Sie die Plusses danach selbst aus.

4
Daniel

Die anderen Antworten enthalten entweder einen manuellen String-Ersatz, URLEncoder , der tatsächlich für das HTML-Format, Apaches aufgegebenURIUtil kodiert, oder Guavas UrlEscapers . Das letzte ist in Ordnung, außer dass es keinen Decoder gibt.

Apache Commons Lang bietet das URLCodec , das und nach URL-Format rfc3986 codiert.

String encoded = new URLCodec().encode(str);
String decoded = new URLCodec().decode(str);

Wenn Sie Spring bereits verwenden, können Sie auch die Klasse itsUriUtils verwenden.

3
Benny Bottema

Ich hatte gerade damit zu kämpfen, auch auf Android, und stolperte über Uri.encode (String, String), während Android (Android.net.Uri) für einige von Vorteil sein könnte. 

statische Zeichenfolgencodierung (Zeichenfolge s, zulässige Zeichenfolge)

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

2
Chrispix

Das hat bei mir funktioniert

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

Obwohl recht alt, trotzdem eine schnelle Antwort: 

Spring bietet UriUtils - damit können Sie angeben, wie kodiert werden soll und welchen Teil es von einem URI betrifft, z.

encodePathSegment
encodePort
encodeFragment
encodeUriVariables
....

Ich benutze sie, weil wir bereits Spring verwenden, d. H., Es ist keine zusätzliche Bibliothek erforderlich!

0
LeO

Benutze ich die falsche Methode? Was ist die richtige Methode, die ich verwenden sollte?

Ja, diese Methode Java.net.URLEncoder.encode wurde nicht für die Konvertierung von "" in "20%" entsprechend der Spezifikation ( source ) erstellt. 

Das Leerzeichen "" wird in ein Pluszeichen "+" umgewandelt.

Auch wenn dies nicht die richtige Methode ist, können Sie dies wie folgt ändern: System.out.println(Java.net.URLEncoder.encode("Hello World", "UTF-8").replaceAll("\\+", "%20"));have Nice day =).

0
Pregunton

Schauen Sie sich die Java.net.URI-Klasse an.

0