Getting request payload from POST request in Java servlet
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:
getReader()
returns a BufferedReader that will allow you to read the body of the request.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())
Fasih Awan
I am a student studying Software Engineering at the University of Waterloo.
Updated on October 07, 2020Comments
-
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()
orrequest.getAttributes()
both end up with no data -
davidfrancis over 11 yearsNo problems, it's a bit hidden that one
-
Vadzim about 10 yearsTake into account that
request.getInputStream()
doesn't honor request character encoding asrequest.getReader()
does. So this example uses default system charset. -
Vadzim about 10 years
new BufferedReader(new InputStreamReader(request.getInputStream()))
could be simplified to justrequest.getReader()
that is already buffered and also preserves request encoding. -
JonnyRaa almost 10 yearsThis 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.html
-
davidfrancis almost 8 yearsThis is interesting, but looks quite inefficient in terms of string concatenation! Any way this can be improved?
-
Oliver Kohll almost 8 yearsString body = request.getReader().lines().collect(Collectors.joining()); may also work. Collectors.joining uses a StringBuilder under the hood apparently.
-
Michael Böckling over 7 yearsI think it should request.getReader().lines().collect(joining("\n")) to preserve the newlines.
-
Benjamin Slabbert almost 7 yearsI 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 over 6 yearsBeware: The parameters are only available if you use the encoding
application/x-www-form-urlencoded
; formultipart/form-data
, you apparently need to access the body part throughrequest.getReader()
and parse it manually. -
Jatin Bodarya over 6 yearsIn 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.lineSeparator(), (accumulator, actual) -> accumulator + actual)
-
shmosel almost 6 yearsYou can replace
(accumulator, actual) -> accumulator + actual
withString::concat
. -
davidfrancis about 5 years@SgtPooki feel free to add some reasoning for that comment, my good sir!
-
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 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 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 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 about 5 yearsLikewise, 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 over 3 yearsThanks sir, this is a clean and concise solution!
-
KnockingHeads about 3 yearsThis 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 almost 3 yearswhy do you append empty string to the SB?
-
Ilya Slyisarenko over 2 yearspublic static String getBody(HttpServletRequest request){ return new String(request.getInputStream().readAllBytes()); }
-
Soroush Shemshadi about 2 yearselse {stringBuilder.append("");} is redundant!