Ottenere il payload della richiesta dalla richiesta POST nel servlet Java


113

Ho una libreria javascript che invia una richiesta POST al mio servlet Java, ma nel doPostmetodo non riesco a ottenere il contenuto del payload della richiesta. Negli strumenti per sviluppatori di Chrome, tutto il contenuto si trova nella sezione Request Payload nella scheda delle intestazioni, e il contenuto è lì, e so che il POST viene ricevuto dal metodo doPost, ma risulta vuoto.

Per l' HttpServletRequest oggetto, in che modo posso ottenere i dati nel payload della richiesta?

Fare request.getParameter()o request.getAttributes() entrambi finiscono senza dati


è necessario specificare quale parametro, ad esempio, se si dispone di una parola chiave nel corpo, utilizzare String keyword = request.getParameter ("keyword");
justMe

Sarebbe interessante vedere il codice JavaScript che invia la richiesta. Apparentemente sta componendo i parametri della richiesta in modo sbagliato.
BalusC

@Razh, beh, sì, lo so, stavo solo specificando quali metodi stavo provando. BalusC Sto usando la libreria resumable.js per gestire i caricamenti di file divisi
Fasih Awan

4
Se non sbaglio, è importante NON utilizzare request.getParameter () prima di leggere dal flusso di input altrimenti non saranno disponibili dati (già letti).
Jeach

Risposte:


110

Risposta semplice:
usa getReader () per leggere il corpo della richiesta

Altre informazioni:
esistono due metodi per leggere i dati nel corpo:

  1. getReader()restituisce un BufferedReader che ti permetterà di leggere il corpo della richiesta.

  2. getInputStream()restituisce un ServletInputStream se è necessario leggere dati binari.

Nota dai documenti: "[Entrambi i metodi] possono essere chiamati per leggere il corpo, non entrambi."


4
Nessun problema, è un po 'nascosto quello
davidfrancis

25
Questo post può essere utile se l'hai appena usato in un filtro e poi hai scoperto che nient'altro può leggere di nuovo il corpo! natch3z.blogspot.co.uk/2009/01/read-request-body-in-filter.html
JonnyRaa

Questa è davvero una brutta risposta.
SgtPooki

1
@SgtPooki sentiti libero di aggiungere qualche motivazione per quel commento, mio ​​buon signore!
davidfrancis

@davidfrancis Non sto cercando di giudicarti personalmente qui, ma: non hai fornito alcun contesto .. nessun link alla documentazione, nessun esempio. La tua risposta al mio commento sembra aver richiesto uno sforzo maggiore della risposta stessa.
SgtPooki

68
String payloadRequest = getBody(request);

Usando questo metodo

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
Tieni presente che request.getInputStream()non rispetta la codifica dei caratteri richiesta come request.getReader()fa. Quindi questo esempio usa il set di caratteri di sistema predefinito.
Vadzim

9
new BufferedReader(new InputStreamReader(request.getInputStream()))potrebbe essere semplificato solo request.getReader()che è già bufferizzato e preserva anche la codifica delle richieste.
Vadzim

1
Ho trovato questa soluzione utile poiché è stata lanciata un'eccezione: javax.servlet.ServletException: java.lang.IllegalStateException: getInputStream() has already been called for this requestquando ho chiamato getReader () perché il lettore era già aperto.
Benjamin Slabbert,

52

È possibile utilizzare Buffer Reader dalla richiesta alla lettura

    // 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

Flussi Java 8

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

Questo è interessante, ma sembra piuttosto inefficiente in termini di concatenazione di stringhe! In qualche modo questo può essere migliorato?
davidfrancis

11
Corpo della stringa = request.getReader (). Lines (). Collect (Collectors.joining ()); può anche funzionare. Collectors.joining utilizza uno StringBuilder sotto il cofano apparentemente.
Oliver Kohll

3
Penso che dovrebbe request.getReader (). Lines (). Collect (join ("\ n")) per preservare le nuove righe.
Michael Böckling

In java 8, lo stream verrà elaborato parallelamente, quindi è necessario aggiungere un metodo sequenziale altrimenti unirà una parte errata di dati - String body = request.getReader (). Lines (). Sequential (). Reduce (System.lineSeparator (), ( accumulatore, effettivo) -> accumulatore + effettivo)
Jatin Bodarya

2
Puoi sostituire (accumulator, actual) -> accumulator + actualcon String::concat.
shmosel


12

Se il contenuto del corpo è una stringa in Java 8 puoi fare:

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


5

Se sei in grado di inviare il payload in JSON, questo è il modo più conveniente per leggere il playload:

Classe di dati di esempio:

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

Payload di esempio (corpo della richiesta):

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

Codice per leggere il payload nel servlet (richiede com.google.gson. *):

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

È tutto. Bello, facile e pulito. Non dimenticare di impostare l'intestazione del tipo di contenuto su application / json.


2

Utilizzando Java 8 prova con le risorse:

    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

Hai solo bisogno

request.getParameterMap ()

per ottenere i parametri POST e GET.

Il metodo restituisce a Map<String,String[]>.

Puoi leggere i parametri nella mappa di

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
Attenzione: i parametri sono disponibili solo se si utilizza la codifica application/x-www-form-urlencoded; perché multipart/form-dataa quanto pare è necessario accedere alla parte del corpo request.getReader()e analizzarla manualmente.
twonkeys
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.