Java-URL-Codierung von Abfragezeichenfolgenparametern

Lesezeit: 8 Minuten

Java URL Codierung von Abfragezeichenfolgenparametern
Benutzer1277546

Angenommen, ich habe eine URL

http://example.com/query?q=

und ich habe eine vom Benutzer eingegebene Abfrage wie:

Zufallswort £500 Bank $

Ich möchte, dass das Ergebnis eine richtig codierte URL ist:

http://example.com/query?q=random%20word%20%A3500%20bank%20%24

Was ist der beste Weg, dies zu erreichen? Ich habe es versucht URLEncoder und das Erstellen von URI/URL-Objekten, aber keines davon kommt ganz richtig heraus.

  • Was meinst du mit “keiner von ihnen kommt ganz richtig heraus”?

    – Markus Elliot

    28. Mai 2012 um 14:12 Uhr

  • Ich habe URI.create verwendet und Leerzeichen durch + in der Abfragezeichenfolge ersetzt. Auf der Client-Site wurde + wieder in Leerzeichen umgewandelt, als ich die Abfragezeichenfolgen auswählte. Das hat bei mir funktioniert.

    – ND27

    17. Juni 2014 um 16:31 Uhr

  • Mögliches Duplikat von Gibt es eine Java-Methode, die eine Sammlung von Parametern als URL-Abfragekomponente codiert?

    – Nick Greally

    13. April 2017 um 5:07 Uhr

  • Warum erwarten Sie, dass $ prozentkodiert ist?

    – jschnasse

    12. April 2018 um 13:46 Uhr


Java URL Codierung von Abfragezeichenfolgenparametern
BalusC

URLEncoder ist der Weg zu gehen. Sie müssen nur daran denken, zu codieren nur der Name und/oder Wert des einzelnen Parameters der Abfragezeichenfolge, nicht die gesamte URL, schon gar nicht das Trennzeichen des Parameters der Abfragezeichenfolge & noch das Parametername-Wert-Trennzeichen =.

String q = "random word £500 bank $";
String url = "https://example.com?q=" + URLEncoder.encode(q, StandardCharsets.UTF_8);

Wenn Sie immer noch nicht auf Java 10 oder neuer sind, verwenden Sie StandardCharsets.UTF_8.toString() als charset-Argument, oder wenn Sie noch nicht auf Java 7 oder neuer sind, dann verwenden Sie "UTF-8".


Beachten Sie, dass Leerzeichen in Abfrageparametern durch dargestellt werden +nicht %20, was rechtsgültig ist. Die %20 wird normalerweise verwendet, um Leerzeichen im URI selbst darzustellen (der Teil vor dem Trennzeichen der URI-Abfragezeichenfolge ?), nicht in der Abfragezeichenfolge (der Teil nach ?).

Beachten Sie auch, dass es drei gibt encode() Methoden. Einer ohne Charset als zweites Argument und ein weiteres mit String als zweites Argument, das eine überprüfte Ausnahme auslöst. Der ohne Charset Argument ist veraltet. Verwenden Sie es niemals und geben Sie immer die an Charset Streit. Die javadoc empfiehlt sogar ausdrücklich, die UTF-8-Codierung zu verwenden, wie von vorgeschrieben RFC3986 und W3C.

Alle anderen Zeichen sind unsicher und werden zunächst mithilfe eines Codierungsschemas 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 Codierungsschema ist UTF-8. Wenn jedoch aus Kompatibilitätsgründen keine Codierung angegeben ist, wird die Standardcodierung der Plattform verwendet.

Siehe auch:

  • Es kann 2 Arten von Parametern in der URL geben. Abfragezeichenfolge (gefolgt von ?) und Pfadparameter (normalerweise Teil der URL selbst). Was ist also mit Pfadparametern? URLEncoder erzeugt + für Leerzeichen auch für Pfadparameter. Tatsächlich verarbeitet es einfach nichts anderes als die Abfragezeichenfolge. Außerdem ist dieses Verhalten nicht mit Node-js-Servern synchron. Daher ist diese Klasse für mich eine Verschwendung und kann nur für sehr spezifische / spezielle Szenarien verwendet werden.

    – Scharadendu sinha

    30. Juli 2017 um 7:15 Uhr


  • @sharadendusinha: wie dokumentiert und beantwortet, URLEncoder ist für URL-kodierte Abfrageparameter konform application/x-www-form-urlencoded Regeln. Pfadparameter passen nicht in diese Kategorie. Stattdessen benötigen Sie einen URI-Encoder.

    – BalusC

    30. Juli 2017 um 13:18 Uhr


  • Wie ich vorhergesagt hatte, würde passieren … Benutzer werden verwirrt, weil das Problem offensichtlich darin besteht, dass die Leute mehr als nur den Parameterwert codieren müssen. Es ist ein sehr seltener Fall, dass Sie nur einen Parameterwert codieren müssen. Deshalb habe ich meine “verwirrte” Wiki-Antwort bereitgestellt, um Leuten wie @sharadendusinha zu helfen.

    – Adam Gent

    3. August 2017 um 12:41 Uhr

  • @WijaySharma: Weil auch URL-spezifische Zeichen kodiert würden. Das sollten Sie nur tun, wenn Sie die gesamte URL als Abfrageparameter einer anderen URL übergeben möchten.

    – BalusC

    15. März 2018 um 9:59 Uhr

  • „+, nicht %20“ ist das, was ich hören musste. Ich danke dir sehr.

    – Wetjosh

    8. August 2019 um 23:00 Uhr

würde ich nicht verwenden URLEncoder. Abgesehen von der falschen Benennung (URLEncoder hat nichts mit URLs zu tun), ineffizient (es verwendet a StringBuffer anstelle von Builder und macht ein paar andere Dinge, die langsam sind) Es ist auch viel zu einfach, es zu vermasseln.

Stattdessen würde ich verwenden URIBuilder oder Frühlings org.springframework.web.util.UriUtils.encodeQuery oder Commons-Apache HttpClient. Der Grund dafür ist, dass Sie den Namen des Abfrageparameters maskieren müssen (dh die Antwort von BalusC q) anders als der Parameterwert.

Der einzige Nachteil des oben Gesagten (das ich schmerzhaft herausgefunden habe) ist das URLs sind keine echte Teilmenge von URIs.

Beispielcode:

import org.apache.http.client.utils.URIBuilder;

URIBuilder ub = new URIBuilder("http://example.com/query");
ub.addParameter("q", "random word £500 bank \$");
String url = ub.toString();

// Result: http://example.com/query?q=random+word+%C2%A3500+bank+%24

Da ich nur auf andere Antworten verlinke, habe ich dies als Community-Wiki markiert. Fühlen Sie sich frei zu bearbeiten.

  • Warum hat das nichts mit URLs zu tun?

    – Luis Sept

    26. Januar 2015 um 14:55 Uhr

  • @ Luis: URLEncoder ist, wie sein Javadoc sagt, dazu bestimmt, Abfragezeichenfolgenparameter konform zu codieren application/x-www-form-urlencoded wie in HTML-Spezifikation beschrieben: w3.org/TR/html4/interact/…. Einige Benutzer verwechseln/missbrauchen es tatsächlich, um ganze URIs zu codieren, wie es der aktuelle Antworter anscheinend getan hat.

    – BalusC

    3. Februar 2015 um 18:15 Uhr


  • @LuisSep kurz URLEncoder dient zum Codieren für die Formularübermittlung. Es dient nicht der Flucht. Es ist nicht die genau Dasselbe Escaping, das Sie verwenden würden, um URLs zu erstellen, die in Ihre Webseite eingefügt werden sollen, aber zufällig so ähnlich ist, dass die Leute es missbrauchen. Sie sollten URLEncoder nur verwenden, wenn Sie einen HTTP-Client schreiben (und selbst dann gibt es weitaus bessere Optionen zum Codieren).

    – Adam Gent

    3. Februar 2015 um 19:48 Uhr

  • @BalusC “Einige Benutzer verwechseln/missbrauchen es tatsächlich, um ganze URIs zu codieren, wie es der aktuelle Antworter anscheinend getan hat.“. Sie haben falsch angenommen. Ich habe nie gesagt, dass ich es vermasselt habe. Ich habe nur andere gesehen, die es getan haben, deren Fehler ich beheben muss. Der Teil, den ich vermasselt habe, ist, dass die Java-URL-Klasse Klammern ohne Escapezeichen akzeptiert, aber nicht die URI-Klasse. Es gibt viele Möglichkeiten, das Erstellen von URLs zu vermasseln, und nicht jeder ist so brillant wie Sie. Ich würde sagen, dass die meisten Benutzer, die auf SO nach URLEncoding suchen, wahrscheinlich “Benutzer verwirren/missbrauchen tatsächlich” URI-Escape.

    – Adam Gent

    3. Februar 2015 um 20:12 Uhr

  • Die Frage bezog sich nicht darauf, aber Ihre Antwort impliziert dies.

    – BalusC

    3. Februar 2015 um 20:14 Uhr


1646716632 751 Java URL Codierung von Abfragezeichenfolgenparametern
M. Abdul Sami

Sie müssen zuerst einen URI erstellen wie:

String urlStr = "http://www.example.com/CEREC® Materials & Accessories/IPS Empress® CAD.pdf"
URL url= new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());

Konvertieren Sie dann diesen Uri in eine ASCII-Zeichenfolge:

urlStr=uri.toASCIIString();

Jetzt ist Ihre URL-Zeichenfolge vollständig codiert. Zuerst haben wir eine einfache URL-Codierung durchgeführt und sie dann in eine ASCII-Zeichenfolge konvertiert, um sicherzustellen, dass keine Zeichen außerhalb von US-ASCII in der Zeichenfolge verbleiben. Genau so machen es Browser.

  • Danke! Es ist dumm, dass Ihre Lösung funktioniert, aber eingebaut URL.toURI() nicht.

    – Benutzer11153

    25. März 2015 um 12:45 Uhr

  • Leider scheint dies nicht mit “file:///” zu funktionieren (zB: “file:///irgendein/Verzeichnis/eine Datei mit Leerzeichen.html”); es bombardiert mit MalformedURLException in „new URL()“; eine Idee, wie man das beheben kann?

    – ZioByte

    30. April 2015 um 10:23 Uhr

  • @tibi Sie können einfach die Methode uri.toString() verwenden, um sie in eine Zeichenfolge anstelle einer Ascii-Zeichenfolge zu konvertieren.

    – M. Abdul Sami

    9. September 2015 um 3:40 Uhr

  • Die API, mit der ich gearbeitet habe, hat die nicht akzeptiert + Ersatz für Leerzeichen, akzeptierte aber %20, daher funktionierte diese Lösung besser als BalusC, danke!

    – Julian Honma

    1. September 2017 um 12:44 Uhr

  • Dies ist eine korrekte Methode zum Codieren der Pfadkomponente der URL. Es ist keine korrekte Methode, Namen oder Werte von Abfrageparametern zu codieren, worum es in der Frage geht.

    – Benutzer207421

    13. Februar 2018 um 1:38 Uhr

1646716633 989 Java URL Codierung von Abfragezeichenfolgenparametern
Emmanuel Tuzery

Guava 15 ist jetzt hinzugekommen eine Reihe einfacher URL-Escaper.

Die Apache Http-Komponentenbibliothek bietet eine praktische Option zum Erstellen und Codieren von Abfrageparametern –

Verwenden Sie mit HttpComponents 4.x –
URLEncodedUtils

Für die Verwendung von HttpClient 3.x –
EncodingUtil

URL url= new URL("http://example.com/query?q=random word £500 bank $");
URI uri = new URI(url.getProtocol(), url.getUserInfo(), IDN.toASCII(url.getHost()), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
String correctEncodedURL=uri.toASCIIString(); 
System.out.println(correctEncodedURL);

Drucke

http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$

Was passiert hier?

1. Teilen Sie die URL in strukturelle Teile auf. Verwenden java.net.URL dafür.

2. Codieren Sie jedes Strukturteil richtig!

3. Verwenden IDN.toASCII(putDomainNameHere) zu Punycode codieren Sie den Hostnamen!

4. Verwenden java.net.URI.toASCIIString() Prozentkodierung, NFC-kodierter Unicode – (besser wäre NFKC!). Weitere Informationen finden Sie unter: So codieren Sie diese URL richtig

In einigen Fällen ist es ratsam zu prüfen, ob die URL bereits verschlüsselt ist. Ersetzen Sie außerdem codierte „+“-Leerzeichen durch codierte „%20“-Leerzeichen.

Hier sind einige Beispiele, die auch richtig funktionieren

{
      "in" : "http://نامه‌ای.com/",
     "out" : "http://xn--mgba3gch31f.com/"
},{
     "in" : "http://www.example.com/‥/foo",
     "out" : "http://www.example.com/%E2%80%A5/foo"
},{
     "in" : "http://search.barnesandnoble.com/booksearch/first book.pdf", 
     "out" : "http://search.barnesandnoble.com/booksearch/first%20book.pdf"
}, {
     "in" : "http://example.com/query?q=random word £500 bank $", 
     "out" : "http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$"
}

Die Lösung besteht rund 100 der von bereitgestellten Testfälle Web-Plattform-Tests.

Hier ist eine Methode, die Sie in Ihrem Code verwenden können, um eine URL-Zeichenfolge und eine Zuordnung von Parametern in eine gültige codierte URL-Zeichenfolge zu konvertieren, die die Abfrageparameter enthält.

String addQueryStringToUrlString(String url, final Map<Object, Object> parameters) throws UnsupportedEncodingException {
    if (parameters == null) {
        return url;
    }

    for (Map.Entry<Object, Object> parameter : parameters.entrySet()) {

        final String encodedKey = URLEncoder.encode(parameter.getKey().toString(), "UTF-8");
        final String encodedValue = URLEncoder.encode(parameter.getValue().toString(), "UTF-8");

        if (!url.contains("?")) {
            url += "?" + encodedKey + "=" + encodedValue;
        } else {
            url += "&" + encodedKey + "=" + encodedValue;
        }
    }

    return url;
}

972280cookie-checkJava-URL-Codierung von Abfragezeichenfolgenparametern

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy