Angenommen, ich habe eine URL
http://example.com/query?q=
und ich habe eine vom Benutzer eingegebene Abfrage wie:
zufälliges Wort £ 500 Bank $
Ich möchte, dass das Ergebnis eine ordnungsgemäß codierte URL ist:
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
Was ist der beste Weg, um dies zu erreichen? Ich habe versucht URLEncoder
, URI / URL-Objekte zu erstellen, aber keines davon ist ganz richtig.
Antworten:
URLEncoder
ist der Weg zu gehen. Sie müssen nur berücksichtigen, dass Sie nur den Namen und / oder den Wert der einzelnen Abfragezeichenfolgenparameter codieren , nicht die gesamte URL, ganz sicher nicht das Trennzeichen für die Abfragezeichenfolgenparameter&
oder das Trennzeichen für den Parameternamen-Wert=
.Beachten Sie, dass Leerzeichen in Abfrageparametern durch
+
nicht dargestellt werden%20
, was rechtmäßig gültig ist. Das%20
wird normalerweise verwendet, um Leerzeichen im URI selbst (dem Teil vor dem Trennzeichen für die URI-Abfragezeichenfolge?
) und nicht in der Abfragezeichenfolge (dem Teil danach?
) darzustellen .Beachten Sie auch, dass es drei
encode()
Methoden gibt. Eines ohneCharset
als zweites Argument und eines mitString
als zweitem Argument, das eine geprüfte Ausnahme auslöst. Der ohneCharset
Argument ist veraltet. Verwenden Sie es niemals und geben Sie immer dasCharset
Argument an. Das Javadoc empfiehlt sogar ausdrücklich die Verwendung der UTF-8-Codierung, wie von RFC3986 und W3C vorgeschrieben .Siehe auch:
quelle
URLEncoder
für URL-codierte Abfrageparameterapplication/x-www-form-urlencoded
Regeln. Pfadparameter passen nicht in diese Kategorie. Sie benötigen stattdessen einen URI-Encoder.Ich würde nicht verwenden
URLEncoder
. Abgesehen davon, dass es falsch benannt ist (URLEncoder
hat nichts mit URLs zu tun), ineffizient ist (es verwendet einStringBuffer
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
URIBuilder
oder Spring'sorg.springframework.web.util.UriUtils.encodeQuery
oder Commons Apache verwendenHttpClient
. Der Grund dafür ist, dass Sie den Namen der Abfrageparameter (dh die Antwort von BalusCq
) anders als den Parameterwert maskieren müssen .Der einzige Nachteil des oben Gesagten (den ich schmerzhaft herausgefunden habe) ist, dass URLs keine echte Teilmenge von URIs sind .
Beispielcode:
Da ich nur auf andere Antworten verweise, habe ich dies als Community-Wiki markiert. Fühlen Sie sich frei zu bearbeiten.
quelle
URLEncoder
ist, wie sein Javadoc sagt, beabsichtigt, Abfragezeichenfolgenparameter zu codieren,application/x-www-form-urlencoded
die der HTML-Spezifikation entsprechen: w3.org/TR/html4/interact/… . Einige Benutzer verwechseln / missbrauchen es tatsächlich für die Codierung ganzer URIs, wie es der aktuelle Antwortende anscheinend getan hat.Sie müssen zuerst einen URI erstellen wie:
Konvertieren Sie dann diesen Uri in einen ASCII-String:
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.
quelle
URL.toURI()
nicht.+
Ersatz für Leerzeichen nicht akzeptiert , aber die% 20 akzeptiert, sodass diese Lösung besser funktioniert als BalusC, danke!Guava 15 hat jetzt eine Reihe einfacher URL-Escaper hinzugefügt .
quelle
URLEncoder
.URLEncoder
nicht der Fall ist.Die Apache Http Components-Bibliothek bietet eine übersichtliche Option zum Erstellen und Codieren von Abfrageparametern.
Verwenden Sie mit HttpComponents 4.x - URLEncodedUtils
Verwenden Sie für HttpClient 3.x - EncodingUtil
quelle
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.
quelle
Druckt
Was passiert hier?
1. Teilen Sie die URL in Strukturteile auf. Verwenden
java.net.URL
Sie dafür.2. Codieren Sie jedes Bauteil richtig!
3. Verwenden Sie Punycode, um den Hostnamen
IDN.toASCII(putDomainNameHere)
zu codieren!4. Verwenden Sie
java.net.URI.toASCIIString()
, um NFC-codierten Unicode in Prozent zu codieren - (besser wäre NFKC!). Weitere Informationen finden Sie unter: So codieren Sie diese URL richtigIn einigen Fällen ist es ratsam zu überprüfen, ob die URL bereits verschlüsselt ist . Ersetzen Sie auch '+' codierte Leerzeichen durch '% 20' codierte Leerzeichen.
Hier sind einige Beispiele, die auch richtig funktionieren
Die Lösung besteht rund 100 der von Web Plattform Tests bereitgestellten Testfälle .
quelle
In Android würde ich diesen Code verwenden:
Wo
Uri
ist einandroid.net.Uri
quelle
In meinem Fall musste ich nur die gesamte URL übergeben und nur den Wert der einzelnen Parameter codieren. Ich habe keinen gemeinsamen Code dafür gefunden (!!), also habe ich diese kleine Methode erstellt, um den Job zu erledigen:
Es verwendet org.apache.commons.lang3.StringUtils
quelle
Sie können den folgenden Code verwenden.
quelle
=
und codiert&
, was nicht korrekt ist.