Abrufen der Anforderungsnutzdaten von der POST-Anforderung im Java-Servlet


113

Ich habe eine Javascript-Bibliothek, die eine POST-Anforderung an mein Java-Servlet sendet, aber in der doPostMethode kann ich den Inhalt der Anforderungsnutzdaten nicht abrufen. In den Chrome Developer Tools befindet sich der gesamte Inhalt im Abschnitt "Payload anfordern" auf der Registerkarte "Header" und der Inhalt ist dort. Ich weiß, dass der POST von der doPost-Methode empfangen wird, aber er wird nur leer angezeigt.

HttpServletRequest Wie kann ich für das Objekt die Daten in der Anforderungsnutzlast abrufen?

Tun request.getParameter()oder request.getAttributes() beide Ende ohne Daten auf


Sie müssen angeben, welcher Parameter verwendet werden soll, z. B. wenn Sie ein Schlüsselwort im Textkörper haben. Verwenden Sie String keyword = request.getParameter ("keyword").
JustMe

Es wäre interessant zu sehen, wie der JavaScript-Code die Anfrage sendet. Anscheinend werden die Anforderungsparameter falsch zusammengesetzt.
BalusC

@Razh gut ja ich weiß, ich habe nur angegeben, welche Methoden ich versucht habe. BalusC Ich benutze die Bibliothek resumable.js, um das Hochladen von geteilten Dateien zu handhaben
Fasih Awan

4
Wenn ich mich nicht irre, ist es wichtig, dass Sie request.getParameter () NICHT vor dem Lesen aus dem Eingabestream verwenden, da sonst keine Daten verfügbar sind (bereits gelesen).
Jeach

Antworten:


110

Einfache Antwort:
Verwenden Sie getReader (), um den Text der Anforderung zu lesen

Weitere Informationen:
Es gibt zwei Methoden zum Lesen der Daten im Körper:

  1. getReader()Gibt einen BufferedReader zurück , mit dem Sie den Hauptteil der Anforderung lesen können.

  2. getInputStream()Gibt einen ServletInputStream zurück, wenn Sie Binärdaten lesen müssen.

Anmerkung aus den Dokumenten: "[Jede Methode] kann aufgerufen werden, um den Textkörper zu lesen, nicht beide."


4
Keine Probleme, es ist ein bisschen versteckt, dass man
Davidfrancis

25
Dieser Beitrag kann nützlich sein, wenn Sie ihn gerade in einem Filter verwendet haben und dann festgestellt haben, dass nichts anderes den Körper wieder lesen kann! natch3z.blogspot.co.uk/2009/01/read-request-body-in-filter.html
JonnyRaa

Das ist eine wirklich schlechte Antwort.
SgtPooki

1
@SgtPooki zögern Sie nicht, einige Gründe für diesen Kommentar hinzuzufügen, mein guter Herr!
Davidfrancis

@davidfrancis Ich versuche hier nicht, Sie persönlich zu beurteilen, aber: Sie haben keinen Kontext angegeben. Kein Link zur Dokumentation, kein Beispiel. Ihre Antwort auf meinen Kommentar scheint mehr Aufwand erfordert zu haben als die Antwort selbst.
SgtPooki

68
String payloadRequest = getBody(request);

Mit dieser Methode

public static String getBody(HttpServletRequest request) throws IOException {

    String body = null;
    StringBuilder stringBuilder = new StringBuilder();
    BufferedReader bufferedReader = null;

    try {
        InputStream inputStream = request.getInputStream();
        if (inputStream != null) {
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            char[] charBuffer = new char[128];
            int bytesRead = -1;
            while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                stringBuilder.append(charBuffer, 0, bytesRead);
            }
        } else {
            stringBuilder.append("");
        }
    } catch (IOException ex) {
        throw ex;
    } finally {
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
            } catch (IOException ex) {
                throw ex;
            }
        }
    }

    body = stringBuilder.toString();
    return body;
}

6
Berücksichtigen Sie, dass request.getInputStream()die Codierung von Anforderungszeichen nicht berücksichtigt request.getReader()wird. In diesem Beispiel wird also der Standard-Systemzeichensatz verwendet.
Vadzim

9
new BufferedReader(new InputStreamReader(request.getInputStream()))könnte vereinfacht werden, damit nur request.getReader()das bereits gepuffert ist und auch die Anforderungscodierung erhalten bleibt.
Vadzim

1
Ich fand diese Lösung hilfreich, da eine Ausnahme ausgelöst wurde: javax.servlet.ServletException: java.lang.IllegalStateException: getInputStream() has already been called for this requestAls ich getReader () aufrief, weil der Reader bereits geöffnet war.
Benjamin Slabbert

52

Sie können den Buffer Reader von der Anforderung zum Lesen verwenden

    // Read from request
    StringBuilder buffer = new StringBuilder();
    BufferedReader reader = request.getReader();
    String line;
    while ((line = reader.readLine()) != null) {
        buffer.append(line);
    }
    String data = buffer.toString()

40

Java 8-Streams

String body = request.getReader().lines()
    .reduce("", (accumulator, actual) -> accumulator + actual);

Dies ist interessant, sieht aber in Bezug auf die Verkettung von Zeichenfolgen ziemlich ineffizient aus! Wie kann dies verbessert werden?
Davidfrancis

11
String body = request.getReader (). Lines (). Collect (Collectors.joining ()); kann auch funktionieren. Collectors.joining verwendet anscheinend einen StringBuilder unter der Haube.
Oliver Kohll

3
Ich denke, es sollte request.getReader (). Lines (). Collect (join ("\ n")) anfordern, um die Zeilenumbrüche beizubehalten.
Michael Böckling

In Java 8 wird der Stream parallel verarbeitet, daher muss eine sequentielle Methode hinzugefügt werden, da sonst ein falscher Teil der Daten zusammengeführt wird - String body = request.getReader (). Lines (). Sequential (). Reduce (System.lineSeparator (), () Akku, aktuell) -> Akku + aktuell)
Jatin Bodarya

2
Sie können ersetzen (accumulator, actual) -> accumulator + actualmit String::concat.
Shmosel


12

Wenn der Inhalt des Körpers in Java 8 eine Zeichenfolge ist, können Sie Folgendes tun:

String body = request.getReader().lines().collect(Collectors.joining());


5

Wenn Sie die Nutzdaten in JSON senden können, ist dies die bequemste Methode zum Lesen der Wiedergabe:

Beispieldatenklasse:

public class Person {
    String firstName;
    String lastName;
    // Getters and setters ...
}

Beispielnutzlast (Anforderungshauptteil):

{ "firstName" : "John", "lastName" : "Doe" }

Code zum Lesen der Nutzdaten im Servlet (erfordert com.google.gson. *):

Person person = new Gson().fromJson(request.getReader(), Person.class);

Das ist alles. Schön, einfach und sauber. Vergessen Sie nicht, den Header für den Inhaltstyp auf application / json zu setzen.


2

Verwenden Sie Java 8 mit Ressourcen:

    StringBuilder stringBuilder = new StringBuilder();
    try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
        char[] charBuffer = new char[1024];
        int bytesRead;
        while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
            stringBuilder.append(charBuffer, 0, bytesRead);
        }
    }

1

Du brauchst nur

request.getParameterMap ()

zum Abrufen der POST- und GET-Parameter.

Die Methode gibt a zurück Map<String,String[]>.

Sie können die Parameter in der Karte von lesen

Map<String, String[]> map = request.getParameterMap();
//Reading the Map
//Works for GET && POST Method
for(String paramName:map.keySet()) {
    String[] paramValues = map.get(paramName);

    //Get Values of Param Name
    for(String valueOfParam:paramValues) {
        //Output the Values
        System.out.println("Value of Param with Name "+paramName+": "+valueOfParam);
    }
}

2
Achtung: Die Parameter sind nur verfügbar, wenn Sie die Codierung verwenden application/x-www-form-urlencoded. für multipart/form-data, müssen Sie offensichtlich den Körperteil durch den Zugriff auf request.getReader()manuell und analysieren.
Schlüssel
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.