Java EE hat ServletRequest.getParameterValues () .
Auf Nicht-EE-Plattformen gibt URL.getQuery () einfach eine Zeichenfolge zurück.
Was ist der normale Weg, um die Abfragezeichenfolge in einer URL richtig zu analysieren, wenn Sie nicht mit Java EE arbeiten?
< rant >
In den Antworten ist es beliebt, einen eigenen Parser zu erstellen. Dies ist ein sehr interessantes und aufregendes Mikrocodierungsprojekt, aber ich kann nicht sagen, dass es eine gute Idee ist :(
Die folgenden Codefragmente sind im Allgemeinen übrigens fehlerhaft oder fehlerhaft. Sie zu brechen ist eine interessante Übung für den Leser. Und zu den Hackern, die die Websites angreifen, die sie verwenden .
Das Parsen von Abfragezeichenfolgen ist ein genau definiertes Problem, aber das Lesen der Spezifikation und das Verstehen der Nuancen ist nicht trivial. Es ist weitaus besser, einen Plattformbibliothekscodierer die harte Arbeit und das Reparieren für Sie erledigen zu lassen!
< / rant >
getQuery()
und was Sie als Ausgabe erhalten möchten?ServletRequest
.Antworten:
Seit Android M sind die Dinge komplizierter geworden. Die Antwort von android.net.URI .getQueryParameter () hat einen Fehler, der Leerzeichen vor JellyBean bricht. Apache URLEncodedUtils.parse () funktionierte, wurde jedoch in L veraltet und in M entfernt .
Die beste Antwort ist jetzt UrlQuerySanitizer . Dies existiert seit API Level 1 und existiert immer noch. Außerdem werden Sie über schwierige Themen wie den Umgang mit Sonderzeichen oder wiederholte Werte nachdenken.
Der einfachste Code ist
Wenn Sie mit dem Standard-Parsing-Verhalten zufrieden sind, können Sie Folgendes tun:
Sie sollten jedoch sicherstellen, dass Sie verstehen, was das Standard-Parsing-Verhalten ist, da es möglicherweise nicht das ist, was Sie wollen.
quelle
UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(YourStringURL);
String value = sanitizer.getValue("parameter");
UrlQuerySanitizer
in SDK-23 hat nur eine Methodesanitize()
_
. Ich musste mit stackoverflow.com/a/35638979/1155282Auf Android:
quelle
Unter Android bieten die Apache-Bibliotheken einen Abfrageparser:
http://developer.android.com/reference/org/apache/http/client/utils/URLEncodedUtils.html und http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/ http / client / utils / URLEncodedUtils.html
quelle
URLEncodedUtils.parse()
einList
Wert zurückgegeben, den Sie dann durchlaufen müssten, um den Wert für einen bestimmten Schlüssel zu ermitteln. Es wäre viel schöner, wenn esMap
in BalusCs Antwort ein ähnliches Ergebnis liefern würde.are
wirklich hilfreich. Einfach zu sehen , einige Vorschläge auf , was mit dem Code falsch sein könnte , ist schon eine große Hilfe für mich zu denken. Und wohlgemerkt, ich wollte nicht sagen, dass "Roll your own is better" ist, sondern dass es großartig ist, gutes Material für eine fundierte Entscheidung in meinem eigenen Code zu haben.Hier ist die Antwort von BalusC , die jedoch Ergebnisse kompiliert und zurückgibt:
quelle
String pair[] = param.split("=");
inString pair[] = param.split("=", 2);
den Schlüssel = Wert - Paar nur auf dem ersten Auftreten zu spalten. Ich glaube, es ist erlaubt, nicht codierte Gleichheitszeichen im Wert zu haben.Wenn Sie Jetty-Bibliotheken (Server oder Client) in Ihrem Klassenpfad haben, können Sie die Jetty-Util-Klassen verwenden (siehe Javadoc ), z.
quelle
Wenn Sie sich mit Spring 3.1 oder höher (Huch, hatte gehofft , dass die Unterstützung weiter ging zurück), können Sie die Verwendung
UriComponents
undUriComponentsBuilder
:components.getQueryParams()
gibt a zurückMultiValueMap<String, String>
Hier finden Sie weitere Dokumentationen .
quelle
Für ein Servlet oder eine JSP-Seite können Sie mithilfe von request.getParameter ("paramname") Querystring-Schlüssel / Wert-Paare abrufen.
Es gibt andere Möglichkeiten, aber so mache ich es in allen Servlets und JSP-Seiten, die ich erstelle.
quelle
Auf Android, habe ich versucht , @diyism Antwort verwenden , aber ich begegnet das Leerzeichen Ausgabe von @rpetrich angehoben, zum Beispiel: ich ein Formular ausfüllen , wo
username = "us+us"
undpassword = "pw pw"
verursacht eine URL - Zeichenfolge zu wie folgt aussehen:Der @ diyism-Code wird jedoch zurückgegeben
"us+us"
und"pw+pw"
erkennt das Leerzeichen nicht. Wenn die URL mit%20
dem Leerzeichen neu geschrieben wurde, wird Folgendes identifiziert:Dies führt zu folgendem Fix:
quelle
replace(" ", "%20")
das fühlt sich falsch an. Aber hat den Trick für mich getan: DDas Parsen der Abfragezeichenfolge ist etwas komplizierter als es scheint, je nachdem, wie verzeihend Sie sein möchten.
Erstens ist die Abfragezeichenfolge ASCII-Bytes. Sie lesen diese Bytes einzeln ein und konvertieren sie in Zeichen. Ist der Charakter? oder & dann signalisiert es den Start eines Parameternamens. Wenn das Zeichen = ist, signalisiert es den Beginn eines Parameterwerts. Wenn das Zeichen% ist, signalisiert es den Beginn eines codierten Bytes. Hier wird es schwierig.
Wenn Sie ein% char einlesen, müssen Sie die nächsten zwei Bytes lesen und sie als hexadezimale Ziffern interpretieren. Das bedeutet, dass die nächsten zwei Bytes 0-9, af oder AF sind. Kleben Sie diese beiden hexadezimalen Ziffern zusammen, um Ihren Bytewert zu erhalten. Aber denken Sie daran, Bytes sind keine Zeichen . Sie müssen wissen, mit welcher Codierung die Zeichen codiert wurden. Das Zeichen é codiert in UTF-8 nicht dasselbe wie in ISO-8859-1. Im Allgemeinen ist es unmöglich zu wissen, welche Codierung für einen bestimmten Zeichensatz verwendet wurde. Ich verwende immer UTF-8, da meine Website so konfiguriert ist, dass immer alles mit UTF-8 bereitgestellt wird, aber in der Praxis können Sie nicht sicher sein. Einige Benutzeragenten teilen Ihnen die Zeichencodierung in der Anforderung mit. Sie können versuchen, dies zu lesen, wenn Sie eine vollständige HTTP-Anfrage haben. Wenn Sie nur eine URL isoliert haben, viel Glück.
Angenommen, Sie verwenden UTF-8 oder eine andere Mehrbyte-Zeichencodierung. Nachdem Sie ein codiertes Byte decodiert haben, müssen Sie es beiseite legen, bis Sie das nächste Byte erfassen. Sie benötigen alle codierten Bytes, die zusammen sind, da Sie nicht jeweils ein Byte richtig url-decodieren können. Legen Sie alle Bytes beiseite, die zusammen sind, und dekodieren Sie sie alle gleichzeitig, um Ihren Charakter zu rekonstruieren.
Außerdem macht es mehr Spaß, wenn Sie nachsichtig sein und Benutzeragenten berücksichtigen möchten, die URLs entstellen. Beispielsweise codieren einige Webmail-Clients Dinge doppelt. Oder verdoppeln Sie die Zeichen? & = (Zum Beispiel :)
http://yoursite.com/blah??p1==v1&&p2==v2
. Wenn Sie versuchen möchten, mit diesem Problem ordnungsgemäß umzugehen, müssen Sie Ihrem Parser mehr Logik hinzufügen.quelle
Unter Android ist es so einfach wie der folgende Code:
Auch wenn Sie nicht jeden erwarteten Abfrageschlüssel registrieren möchten, verwenden Sie:
Vor dem Anruf:
quelle
Ich habe Methoden, um dies zu erreichen:
1) :
2) und der einfachste Weg, dies mit der Uri- Klasse zu tun :
Dies ist ein Beispiel für die Verwendung einer von zwei Methoden:
Der Wert von tagValue ist
800
quelle
Unter Android können Sie die statische Methode Uri.parse der Klasse android.net.Uri verwenden , um das schwere Heben durchzuführen . Wenn Sie etwas mit URIs und Absichten tun, sollten Sie es trotzdem verwenden.
quelle
Nur als Referenz, dies ist, was ich am Ende (basierend auf URLEncodedUtils und Rückgabe einer Karte).
Eigenschaften:
request.getQueryString()
).Map
List<String>
Code:
Ein Kompatibilitätshelfer (Werte werden wie in ServletRequest.getParameterMap () in einem String-Array gespeichert ):
quelle
Das funktioniert bei mir. Ich bin mir nicht sicher, warum jeder nach einer Karte, Liste> Alles was ich brauchte war eine einfache Namenswertkarte.
Um die Dinge einfach zu halten, habe ich den Build in URI.getQuery () verwendet.
quelle
Dafür ist Guavas Multimap besser geeignet. Hier ist eine kurze saubere Version:
quelle
Apache AXIS2 verfügt über eine eigenständige Implementierung von QueryStringParser.java. Wenn Sie Axis2 nicht verwenden, laden Sie einfach den Quellcode und den Testfall von hier herunter -
http://svn.apache.org/repos/asf/axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/transport/http/util/QueryStringParser.java
http://svn.apache.org/repos/asf/axis/axis2/java/core/trunk/modules/kernel/test/org/apache/axis2/transport/http/util/QueryStringParserTest.java
quelle
Ursprünglich hier beantwortet
Unter Android gibt es die Uri-Klasse im Paket android.net . Beachten Sie, dass Uri Teil von android.net ist, während URI Teil von java.net ist.
Die Uri-Klasse verfügt über viele Funktionen zum Extrahieren von Abfrage-Schlüssel-Wert-Paaren.
Die folgende Funktion gibt Schlüssel-Wert-Paare in Form von HashMap zurück.
In Java:
In Kotlin:
quelle
Ich glaube nicht, dass es einen in JRE gibt. Sie können ähnliche Funktionen in anderen Paketen wie Apache HttpClient finden. Wenn Sie keine anderen Pakete verwenden, müssen Sie nur Ihre eigenen schreiben. Es ist nicht so schwer. Hier ist was ich benutze,
quelle
Basierend auf der Antwort von BalusC habe ich einen Beispiel-Java-Code geschrieben:
quelle
quelle
Verwenden Sie Apache HttpComponents und verbinden Sie es mit einem Auflistungscode, um auf Parameter nach Wert zuzugreifen: http://www.joelgerard.com/2012/09/14/parsing-query-strings-in-java-and-accessing-values-by -Schlüssel/
quelle
mit Guave:
quelle
Hier antworten, weil dies ein beliebter Thread ist. Dies ist eine saubere Lösung in Kotlin, die die empfohlene
UrlQuerySanitizer
API verwendet. Siehe die offizielle Dokumentation . Ich habe einen String Builder hinzugefügt, um die Parameter zu verketten und anzuzeigen.quelle
Diese Methode verwendet die Uri- und Rückgabekarte von Par-Name und Par-Wert
quelle
Sie sagen "Java", aber "nicht Java EE". Meinen Sie damit, dass Sie JSP und / oder Servlets verwenden, aber keinen vollständigen Java EE-Stack? Wenn dies der Fall ist, sollte Ihnen weiterhin request.getParameter () zur Verfügung stehen.
Wenn Sie meinen, Sie schreiben Java, aber Sie schreiben keine JSPs oder Servlets oder Sie verwenden nur Java als Referenzpunkt, aber Sie befinden sich auf einer anderen Plattform, die keine integrierte Parameteranalyse hat ... Wow , das klingt nur nach einer unwahrscheinlichen Frage, aber wenn ja, wäre das Prinzip:
(Ich könnte Java-Code schreiben, aber das wäre sinnlos, denn wenn Sie Java zur Verfügung haben, können Sie einfach request.getParameters verwenden.)
quelle