Java sunucu uygulamasında POST isteğinden yük talebi alma


113

Java sunucu uygulamama POST isteği gönderen bir javascript kitaplığım var, ancak doPostyöntemde istek yükünün içeriğini alamıyorum. Chrome Geliştirici Araçlarında, tüm içerik, üstbilgiler sekmesindeki Yük İste bölümündedir ve içerik oradadır ve POST'un doPost yöntemi tarafından alındığını biliyorum, ancak boş çıkıyor.

İçin HttpServletRequest nesne, ne şekilde ben isteği bilgisi veri alabilirim?

Yapmak request.getParameter()veya request.getAttributes() her ikisi de veri olmadan sonuçlanır


hangi parametreyi belirtmeniz gerekir; örneğin, gövdede anahtar kelimeniz varsa String keyword = request.getParameter ("anahtar kelime") kullanın;
justMe

İsteği gönderen JavaScript kodunu görmek ilginç olurdu. Görünüşe göre istek parametrelerini yanlış bir şekilde oluşturuyor.
BalusC

@Razh iyi evet biliyorum, sadece hangi yöntemleri denediğimi belirtiyordum. BalusC Bölünmüş dosya yüklemelerini işlemek için resumable.js kitaplığını kullanıyorum
Fasih Awan

4
Yanılmıyorsam, giriş akışından okumadan önce request.getParameter () KULLANMAMANIZ önemlidir, aksi takdirde hiçbir veri mevcut olmayacaktır (zaten okunmuş).
Jeach

Yanıtlar:


110

Basit cevap:
İsteğin metnini okumak için getReader () kullanın

Daha fazla bilgi:
Vücuttaki verileri okumak için iki yöntem vardır:

  1. getReader()isteğin gövdesini okumanıza izin verecek bir BufferedReader döndürür .

  2. getInputStream()ikili verileri okumanız gerekiyorsa ServletInputStream döndürür .

Dokümanlardan not: "Gövdeyi okumak için [iki yöntemden biri] çağrılabilir, ikisi birden değil."


4
Sorun yok, bu biraz gizli
davidfrancis

25
Bu gönderi, bunu bir filtrede kullandıysanız ve sonra başka hiçbir şeyin bedeni tekrar okuyamayacağını keşfettiğinizde yararlı olabilir! natch3z.blogspot.co.uk/2009/01/read-request-body-in-filter.html
JonnyRaa

Bu gerçekten kötü bir cevap.
SgtPooki

1
@SgtPooki bu yorum için bir sebep eklemekten çekinmeyin, efendim!
davidfrancis

@davidfrancis Sizi burada şahsen yargılamaya çalışmıyorum, ancak: hiçbir bağlam sağlamadınız .. belgelere bağlantı yok, örnek yok. Yorumuma cevabınız, cevabın kendisinden daha fazla çaba gerektirmiş görünüyor.
SgtPooki

68
String payloadRequest = getBody(request);

Bu yöntemi kullanarak

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
request.getInputStream()İsteğin karakter kodlamasını olduğu gibi kabul request.getReader()etmediğini dikkate alın . Dolayısıyla bu örnek, varsayılan sistem karakter kümesini kullanır.
Vadzim

9
new BufferedReader(new InputStreamReader(request.getInputStream()))sadece request.getReader()zaten arabelleğe alınmış olacak şekilde basitleştirilebilir ve ayrıca istek kodlamasını korur.
Vadzim

1
Bir istisna atıldığından bu çözümü yararlı buldum: javax.servlet.ServletException: java.lang.IllegalStateException: getInputStream() has already been called for this requestokuyucunun zaten açık olması nedeniyle getReader () 'i çağırdığımda.
Benjamin Slabbert

52

Buffer Reader'ı okuma isteğinden kullanabilirsiniz.

    // 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 akışları

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

Bu ilginç, ancak dizgi birleştirme açısından oldukça verimsiz görünüyor! Herhangi bir şekilde iyileştirilebilir mi?
davidfrancis

11
Dize gövdesi = request.getReader (). Satırlar (). Collect (Collectors.joining ()); ayrıca çalışabilir. Collectors.joining, görünüşe göre kaputun altında bir StringBuilder kullanıyor.
Oliver Kohll

3
Yeni satırları korumak için request.getReader (). Lines (). Collect (katılarak ("\ n")) gerektiğini düşünüyorum.
Michael Böckling

Java 8'de akış paralel olarak işleneceğinden sıralı yöntem eklemesi gerekir, aksi takdirde verilerin yanlış kısmını birleştirir - String body = request.getReader (). Lines (). Sequential (). Lower (System.lineSeparator (), ( akümülatör, gerçek) -> akümülatör + gerçek)
Jatin Bodarya

2
Sen yerini alabilir (accumulator, actual) -> accumulator + actualile String::concat.
shmosel


12

Gövde içeriği Java 8'de bir dizeyse şunları yapabilirsiniz:

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


5

Yükü JSON biçiminde gönderebiliyorsanız, bu, oynatma yükünü okumanın en uygun yoludur:

Örnek veri sınıfı:

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

Örnek yük (istek gövdesi):

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

Sunucu uygulamasında yükü okumak için kod (com.google.gson. * Gerektirir):

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

Bu kadar. Güzel, kolay ve temiz. Content-type başlığını application / json olarak ayarlamayı unutmayın.


2

Java 8 kullanarak kaynaklarla deneyin:

    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

Sadece ihtiyacın var

request.getParameterMap ()

POST ve GET - Parametrelerini almak için.

Yöntem bir Map<String,String[]> .

Haritadaki parametreleri okuyabilirsiniz.

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
Dikkat: Parametreler yalnızca kodlamayı kullanırsanız kullanılabilir application/x-www-form-urlencoded; çünkü multipart/form-datagörünüşe göre vücut kısmına erişmeniz request.getReader()ve onu manuel olarak ayrıştırmanız gerekiyor.
twonkeys
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.