Getting request payload from POST request in Java servlet

316,860

Solution 1

Simple answer:
Use getReader() to read the body of the request

More info:
There are two methods for reading the data in the body:

  1. getReader() returns a BufferedReader that will allow you to read the body of the request.

  2. getInputStream() returns a ServletInputStream if you need to read binary data.

Note from the docs: "[Either method] may be called to read the body, not both."

Solution 2

String payloadRequest = getBody(request);

Using this method

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;
}

Solution 3

You can use Buffer Reader from request to read

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

Solution 4

Java 8 streams

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

Solution 5

With Apache Commons IO you can do this in one line.

IOUtils.toString(request.getReader())
Share:
316,860
Fasih Awan
Author by

Fasih Awan

I am a student studying Software Engineering at the University of Waterloo.

Updated on October 07, 2020

Comments

  • Fasih Awan
    Fasih Awan over 3 years

    I have a javascript library that is sending a POST request to my Java servlet, but in the doPost method, I can't seem to get the contents of the request payload. In chrome Developer Tools, all the content is in the Request Payload section in the headers tab, and the content is there, and I know that the POST is being received by the doPost method, but it just comes up blank.

    For the HttpServletRequest object, what way can I get the data in the request payload?

    Doing request.getParameter() or request.getAttributes() both end up with no data

  • davidfrancis
    davidfrancis over 11 years
    No problems, it's a bit hidden that one
  • Vadzim
    Vadzim about 10 years
    Take into account that request.getInputStream() doesn't honor request character encoding as request.getReader() does. So this example uses default system charset.
  • Vadzim
    Vadzim about 10 years
    new BufferedReader(new InputStreamReader(request.getInputStream())) could be simplified to just request.getReader() that is already buffered and also preserves request encoding.
  • JonnyRaa
    JonnyRaa almost 10 years
    This post may be useful if you've just used this in a filter and then discovered nothing else can read the body again! natch3z.blogspot.co.uk/2009/01/read-request-body-in-filter.h‌​tml
  • davidfrancis
    davidfrancis almost 8 years
    This is interesting, but looks quite inefficient in terms of string concatenation! Any way this can be improved?
  • Oliver Kohll
    Oliver Kohll almost 8 years
    String body = request.getReader().lines().collect(Collectors.joining()); may also work. Collectors.joining uses a StringBuilder under the hood apparently.
  • Michael Böckling
    Michael Böckling over 7 years
    I think it should request.getReader().lines().collect(joining("\n")) to preserve the newlines.
  • Benjamin Slabbert
    Benjamin Slabbert almost 7 years
    I found this solution helpful as an exception was thrown: javax.servlet.ServletException: java.lang.IllegalStateException: getInputStream() has already been called for this request when I called getReader() as a result of the reader already being open.
  • twonkeys
    twonkeys over 6 years
    Beware: The parameters are only available if you use the encoding application/x-www-form-urlencoded; for multipart/form-data, you apparently need to access the body part through request.getReader() and parse it manually.
  • Jatin Bodarya
    Jatin Bodarya over 6 years
    In java 8,stream will be processed parallely so need to add sequential method otherwise it will merge wrong portion of data - String body = request.getReader().lines().sequential().reduce(System.lineS‌​eparator(), (accumulator, actual) -> accumulator + actual)
  • shmosel
    shmosel almost 6 years
    You can replace (accumulator, actual) -> accumulator + actual with String::concat.
  • davidfrancis
    davidfrancis about 5 years
    @SgtPooki feel free to add some reasoning for that comment, my good sir!
  • SgtPooki
    SgtPooki about 5 years
    @davidfrancis I'm not trying to judge you personally here, but: you have provided no context.. no link to documentation, no example. Your reply to my comment seems to have required more effort than the answer itself.
  • davidfrancis
    davidfrancis about 5 years
    @SgtPooki Correct, as none of those things are needed. IMHO the name of the method needed is somewhat obscure, hence the method name is the answer to this question. Simple as that I thought. Feel free to submit a longer answer if you think it would be useful.
  • SgtPooki
    SgtPooki about 5 years
    @davidfrancis, you're missing the point. The actual question is "How do I get data from the request". Now try, with your answer as it stands, to get data by writing req.getReader(). Does that give you the data in the request payload, or does it give you the reader, which facilitates getting the body of the request?
  • davidfrancis
    davidfrancis about 5 years
    @sgtPooki Your answer is more detailed, but it has extraneous detail that may not be useful. Many people using this API will not be interested in reading the body line by line at all, they will be parsing the body using a library e.g. as JSON. IMHO you should really have submitted it as a new answer because it's no longer my text.
  • davidfrancis
    davidfrancis about 5 years
    Likewise, I hope if your day job you don't overwrite code without discussion first, if you don't like it - even if 93 previous people happened to like it. I read around about the etiquette of editing answers so am fully up to date with the various opinions 8=}. Thanks for your input to the answer.
  • obayral
    obayral over 3 years
    Thanks sir, this is a clean and concise solution!
  • KnockingHeads
    KnockingHeads about 3 years
    This worked in my case where I had to implement JWT authentication. I was sending JSON payload with username and password, then mapped that to my custom Auth Token class.
  • Li3ro
    Li3ro almost 3 years
    why do you append empty string to the SB?
  • Ilya Slyisarenko
    Ilya Slyisarenko over 2 years
    public static String getBody(HttpServletRequest request){ return new String(request.getInputStream().readAllBytes()); }
  • Soroush Shemshadi
    Soroush Shemshadi about 2 years
    else {stringBuilder.append("");} is redundant!