Mendapatkan payload permintaan dari permintaan POST di servlet Java


113

Saya memiliki pustaka javascript yang mengirimkan permintaan POST ke servlet Java saya, tetapi dalam doPostmetode ini, saya tidak bisa mendapatkan konten dari muatan permintaan. Di Chrome Developer Tools, semua konten ada di bagian Minta Payload di tab header, dan kontennya ada di sana, dan saya tahu bahwa POST sedang diterima oleh metode doPost, tetapi hasilnya kosong.

Untuk HttpServletRequest objek, dengan cara apa saya bisa mendapatkan data di payload permintaan?

Melakukan request.getParameter()atau request.getAttributes() keduanya berakhir tanpa data


Anda perlu menentukan parameter mana misalnya jika Anda memiliki kata kunci dalam tubuh gunakan String keyword = request.getParameter ("keyword");
justMe

Menarik untuk melihat kode JavaScript yang mengirimkan permintaan tersebut. Tampaknya menyusun parameter permintaan dengan cara yang salah.
BalusC

@Razh baik ya saya tahu, saya baru saja menentukan metode mana yang saya coba. BalusC Saya menggunakan perpustakaan resumable.js untuk menangani unggahan file yang terbagi
Fasih Awan

4
Jika saya tidak salah, penting bagi Anda untuk JANGAN menggunakan request.getParameter () sebelum membaca dari aliran input jika tidak, data tidak akan tersedia (sudah dibaca).
Jeach

Jawaban:


110

Jawaban sederhana:
Gunakan getReader () untuk membaca isi permintaan

Info selengkapnya:
Ada dua metode untuk membaca data di body:

  1. getReader()mengembalikan BufferedReader yang memungkinkan Anda membaca isi permintaan.

  2. getInputStream()mengembalikan ServletInputStream jika Anda perlu membaca data biner.

Catatan dari dokumen: "[Metode mana pun] dapat dipanggil untuk membaca isi, bukan keduanya."


4
Tidak masalah, itu agak tersembunyi
davidfrancis

25
Posting ini mungkin berguna jika Anda baru saja menggunakan ini di filter dan kemudian menemukan tidak ada lagi yang dapat membaca isi lagi! natch3z.blogspot.co.uk/2009/01/read-request-body-in-filter.html
JonnyRaa

Ini jawaban yang sangat buruk.
SgtPooki

1
@SgtPooki jangan ragu untuk menambahkan beberapa alasan untuk komentar itu, Pak!
davidfrancis

@davidfrancis Saya tidak mencoba menilai Anda secara pribadi di sini, tetapi: Anda tidak memberikan konteks .. tidak ada tautan ke dokumentasi, tidak ada contoh. Balasan Anda untuk komentar saya tampaknya membutuhkan lebih banyak usaha daripada jawaban itu sendiri.
SgtPooki

68
String payloadRequest = getBody(request);

Menggunakan metode ini

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
Mempertimbangkan bahwa request.getInputStream()tidak menghormati pengkodean karakter permintaan seperti request.getReader()halnya. Jadi contoh ini menggunakan charset sistem default.
Vadzim

9
new BufferedReader(new InputStreamReader(request.getInputStream()))dapat disederhanakan menjadi hanya request.getReader()yang sudah di-buffer dan juga mempertahankan encoding permintaan.
Vadzim

1
Saya menemukan solusi ini bermanfaat karena pengecualian dilemparkan: javax.servlet.ServletException: java.lang.IllegalStateException: getInputStream() has already been called for this requestketika saya memanggil getReader () sebagai akibat dari pembaca sudah terbuka.
Benjamin Slabbert

52

Anda dapat menggunakan Buffer Reader dari permintaan untuk membaca

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

Aliran Java 8

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

Ini menarik, tetapi terlihat sangat tidak efisien dalam hal penggabungan string! Adakah cara agar hal ini dapat ditingkatkan?
davidfrancis

11
String body = request.getReader (). Lines (). Collect (Collectors.joining ()); mungkin juga bekerja. Collectors.joining menggunakan StringBuilder di bawah tenda.
Oliver Kohll

3
Saya pikir itu harus request.getReader (). Lines (). Collect (bergabung ("\ n")) untuk mempertahankan baris baru.
Michael Böckling

Di java 8, aliran akan diproses secara paralel sehingga perlu menambahkan metode sekuensial jika tidak maka akan menggabungkan bagian data yang salah - String body = request.getReader (). Lines (). Sequential (). Reduce (System.lineSeparator (), ( akumulator, aktual) -> akumulator + aktual)
Jatin Bodarya

2
Anda bisa mengganti (accumulator, actual) -> accumulator + actualdengan String::concat.
shmosel


12

Jika isi body berupa string di Java 8 Anda bisa melakukan:

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


5

Jika Anda dapat mengirim payload dalam JSON, ini adalah cara paling nyaman untuk membaca playload:

Contoh kelas data:

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

Contoh payload (isi permintaan):

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

Kode untuk membaca payload di servlet (membutuhkan com.google.gson. *):

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

Itu saja. Bagus, mudah dan bersih. Jangan lupa untuk mengatur header tipe konten ke application / json.


2

Menggunakan Java 8 coba dengan sumber daya:

    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

Anda hanya butuh

request.getParameterMap ()

untuk mendapatkan POST dan GET - Parameter.

Metode mengembalikan a Map<String,String[]>.

Anda dapat membaca parameter di Peta dengan

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
Hati-hati: Parameter hanya tersedia jika Anda menggunakan pengkodean application/x-www-form-urlencoded; Sebab multipart/form-data, Anda tampaknya perlu mengakses bagian tubuh melalui request.getReader()dan menguraikannya secara manual.
twonkeys
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.