HttpServletRequest - Abfragezeichenfolgenparameter abrufen, keine Formulardaten


76

Gibt in HttpServletRequestgetParameterMap eine Zuordnung aller Abfragezeichenfolgenparameter und Postdatenparameter zurück.

Gibt es eine Möglichkeit, eine Karte mit NUR Abfragezeichenfolgenparametern zu erhalten? Ich versuche zu vermeiden, getQueryString zu verwenden und die Werte zu analysieren.


15
Sie können beides haben ... Sie können Abfragezeichenfolgenparameter für eine POST-Anforderung haben. Und in diesem Fall werden sie alle von "getParameterMap"
JasonStoltz

Oh ok. Warum braucht man beides, nur neugierig?
Jacob

2
Weil auf der resultierenden Seite eine Abfragezeichenfolge in der URL / in der Abfragezeichenfolge angezeigt werden soll. Wir haben ein Tracking-System, das nach bestimmten Parametern in der Abfragezeichenfolge sucht.
JasonStoltz

req.getParameterMap (). enthältKey ("Benutzername");
Parag Jadhav

Antworten:


22

Im Gegensatz zu Cularis kann es in der Parameterkarte beides geben.

Der beste Weg, den ich sehe, besteht darin, die parameterMap zu vertreten und bei jedem Parameterabruf zu überprüfen, ob queryString "&? <Parametername> =" enthält.

Beachten Sie, dass parameterName URL-codiert sein muss, bevor diese Prüfung durchgeführt werden kann, wie Qerub hervorhob.

Das erspart Ihnen das Parsen und gibt Ihnen immer noch nur URL-Parameter.


2
Beachten Sie, dass parameterNameeine URL-Codierung erforderlich ist, bevor diese Prüfung durchgeführt werden kann.
Qerub

12
Die Abfragezeichenfolge enthält niemals ?. Das ist das Trennzeichen zwischen URI und Abfragezeichenfolge.
BalusC

Hallo @DoubleMalt, ich habe die gleiche Anforderung, kann aber die von Ihnen bereitgestellte Lösung nicht erhalten. Können Sie Beispielcode bereitstellen?
Vishal Zanzrukia

@ VishalZanzrukia: Was ist dein Code, der nicht funktioniert?
DoubleMalt

1
Ich mag die Idee, aber es gibt nicht immer ein "=" Zeichen in der Abfragezeichenfolge. Wenn der Parameterwert leer ist, enthält die Abfragezeichenfolge nur <Parametername>. Ich persönlich denke, eine Aufteilung durch "&" und "=" wäre eine bessere Lösung.
Bren

95

Sie können verwenden request.getQueryString(), wenn die Abfragezeichenfolge wie ist

username=james&password=pwd

Um einen Namen zu erhalten, können Sie dies tun

request.getParameter("username"); 

Dies ist für die Verwendung auf Java Server-Seiten vorgesehen.
Jorgesys

2
Der zweite wird den Anforderungsstrom verderben. Ich
gehe

23

Der Servlet-API fehlt diese Funktion, da sie in einer Zeit erstellt wurde, in der viele glaubten, dass die Abfragezeichenfolge und der Nachrichtentext nur zwei verschiedene Arten des Sendens von Parametern waren, ohne zu erkennen, dass die Zwecke der Parameter grundlegend unterschiedlich sind.

Die Abfragezeichenfolgenparameter? Foo = bar sind Teil der URL, da sie an der Identifizierung einer Ressource beteiligt sind (die eine Sammlung vieler Ressourcen sein kann), z. B. "alle Personen im Alter von 42 Jahren":

GET / Personen? Alter = 42

Die Nachrichtentextparameter in POST oder PUT dienen dazu, eine Änderung an den Zielressourcen auszudrücken. Fx einen Wert auf das Attribut "Haar" setzen:

PUT / Personen? Alter = 42

Haare = grau

Es ist also auf jeden Fall RESTful, sowohl Abfrageparameter als auch Body-Parameter gleichzeitig zu verwenden, getrennt, damit Sie sie für verschiedene Zwecke verwenden können. Die Funktion fehlt definitiv in der Java-Servlet-API.


12

Wie in den anderen Antworten angegeben, gibt es keine Möglichkeit, Abfragezeichenfolgenparameter mithilfe der Servlet-API abzurufen.

Ich denke, der beste Weg, um Abfrageparameter zu erhalten, besteht darin, die Abfragezeichenfolge selbst zu analysieren. (Es ist komplizierter, Parameter zu durchlaufen und zu überprüfen, ob die Abfragezeichenfolge den Parameter enthält.)

Ich habe unten Code geschrieben, um Abfragezeichenfolgenparameter zu erhalten. Verwenden von Apache StringUtils und ArrayUtils, die auch CSV-getrennte Abfrageparameterwerte unterstützen.

Beispiel: username=james&username=smith&password=pwd1,pwd2wird zurückkehren

password : [pwd1, pwd2] (Länge = 2)

username : [james, smith] (Länge = 2)

public static Map<String, String[]> getQueryParameters(HttpServletRequest request) throws UnsupportedEncodingException {
    Map<String, String[]> queryParameters = new HashMap<>();
    String queryString = request.getQueryString();
    if (StringUtils.isNotEmpty(queryString)) {
        queryString = URLDecoder.decode(queryString, StandardCharsets.UTF_8.toString());
        String[] parameters = queryString.split("&");
        for (String parameter : parameters) {
            String[] keyValuePair = parameter.split("=");
            String[] values = queryParameters.get(keyValuePair[0]);
            //length is one if no value is available.
            values = keyValuePair.length == 1 ? ArrayUtils.add(values, "") :
                    ArrayUtils.addAll(values, keyValuePair[1].split(",")); //handles CSV separated query param values.
            queryParameters.put(keyValuePair[0], values);
        }
    }
    return queryParameters;
}

Ich halte dies für viel besser als die akzeptierte Antwort. Ich weiß nicht, warum ich das Parsen von
Abfragezeichenfolgen

1
Ich frage mich nur, ob einer der Abfrageparameter &Zeichen in seinem Wert enthält, ob er Ihnen das richtige Ergebnis
liefert

1
@amdg - dieses Zeichen wäre URL-codiert, so dass der Code gut ist. Wenn es nicht codiert wäre, wäre die Zeichenfolge nicht analysierbar.
Marathon

Erwägen Sie auch die Verwendung von URLDecoder.decode(keyValuePair[0])(oder [1]): docs.oracle.com/javase/6/docs/api/java/net/URLDecoder.html
Pluto

1
Abfrageparameter mit CSV-getrennten Werten werden hier nicht berücksichtigt. Zum Beispiel: username=james&username=smith&password=pwd1,pwd2wird eine Karte mit 2 Werten für den Benutzernamen (was korrekt ist), aber nur 1 Wert für das Passwort (was falsch ist) haben
Niv

4

Java 8

return Collections.list(httpServletRequest.getParameterNames())
                  .stream()
                  .collect(Collectors.toMap(parameterName -> parameterName, httpServletRequest::getParameterValues));

2

Ich befürchte, es gibt keine Möglichkeit, die Parameter der Abfragezeichenfolge getrennt von den Post-Parametern zu analysieren. Übrigens kann die Tatsache, dass eine solche API fehlt, bedeuten, dass Sie wahrscheinlich Ihr Design überprüfen sollten. Warum verwenden Sie beim Senden von POST eine Abfragezeichenfolge? Wenn Sie wirklich mehr Daten in eine URL senden möchten, verwenden Sie die REST-ähnliche Konvention, z. B. anstatt zu senden

http://mycompany.com/myapp/myservlet?first=11&second=22

sagen:

http://mycompany.com/myapp/myservlet/11/22


Ich verwende den Parameter für Abfragezeichenfolgen in einem POST, weil ich alle Abfragezeichenfolgen beibehalten möchte, die über den POST an das ursprüngliche Formular übergeben wurden. Dies dient hauptsächlich zu Verfolgungszwecken ... Ich bin nicht sicher, ob die REST-ähnliche Konvention in diesem Fall funktionieren würde, da ich ziemlich sicher bin, dass die Verfolgungsbibliothek nach bestimmten Parametern in der Abfragezeichenfolge sucht.
JasonStoltz

Gibt es insbesondere einen Grund, warum Sie die Verwendung der REST-ähnlichen Konvention für einen Abfragezeichenfolgenparameter empfehlen würden? Nicht sicher, ob ich verstehe, was der Vorteil ist?
JasonStoltz

8
"Übrigens kann die Tatsache, dass eine solche API fehlt, bedeuten, dass Sie wahrscheinlich Ihr Design überprüfen sollten." In diesem Fall bedeutet dies, dass Oracle das Design überprüfen sollte :)
Stijn de Witt
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.