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.

JasonStoltz
quelle
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.

DoubleMalt
quelle
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"); 
Küste
quelle
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.

Ola Berg
quelle
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;
}
Bren
quelle
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));
Giani Segatto
quelle
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

AlexR
quelle
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