I am in the situation where my application needs to inspect the content/data/body/payload of a POST request without changing the results of subsequent getParameter calls.
Reading the body from the inputStream:
The body can be read using the InputStream from request.getInputStream
or BufferedReader from request.getReader
.
Reading POST parameters:
POST requests typically include request parameters in the body of the request. These can be retrieved using getParameter
.
The Problem:
the first getParameter
call internally parses the inputStream and inserts all parameters into a parameter HashMap. It requires the inputStream to still contain the contents for parsing. Thus one cannot inspect the content and still have a working getParameter call.
Proposed (but not sufficient) Solution
Create a request wrapper that caches the inputstream and returns the cache for getInputStream.
I've seen that solution suggested all over the web, but it doesn't work, because getParameter
doesn't actually call getInputStream
, but refers to the original inputBuffer buried in the request object. I've tried it, both from within the Servlet and by using a filter
The only solution I can think of involves rewriting getParameter to actually parse the cached inputstream manually. But this feels like a bad idea.
Does anybody have any alternative that works? (This is Tomcat 5.5) This feels like it should be a common use-case; I can't believe how difficult it is.
getParameter() method to get the value of a form parameter. getParameterValues() − Call this method if the parameter appears more than once and returns multiple values, for example checkbox. getParameterNames() − Call this method if you want a complete list of all parameters in the current request.
getParameter(java.lang.String name) Returns the value of a request parameter as a String , or null if the parameter does not exist.
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.
(That's a rather old tomcat, I'm assuming upgrading to a more modern one isn't an option.)
What you want to do will require intercepting the construction of the concrete HttpServletResponse object wrapping the underlying InputStream. Wrapping that InputStream in a push-back input stream (or equivalent) is necessary.
Tomcat 5.5 is so old I can't even think how that would be accomplished 'normally', but perhaps you could write a filter that uses reflection to reach in and swap the InputStream object inside the concrete request object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With