Hi guys,

I'm using Spring Boot version 1.4.2.RELEASE. Not sure if this is an issue or perhaps a wrong usage of ContentCachingRequestWrapper.

I have 3 custom filters in my filter chain that needs to work with the request body, so for this I used ContentCachingRequestWrapper.

However, I noticed that I could read multiple time the content of the request by executing getContentAsByteArray only if I call first getInputStream. However, getInputStream consumes the request and the filters don't work.

I think getInputStream should be a decorated method that returns always a copy of the input stream. I have moved with this implementation in SO of a request wrapper: https://stackoverflow.com/questions/10210645/http-servlet-request-lose-params-from-post-body-after-read-it-once and everything works good.

The only difference I see between spring's wrapper and SO wrapper is that SO uses IOUtils.copy from apache common.

Is this an issue with ContentCachingRequestWrapper ?

Comment From: snicoll

Hard to tell but there's no such class in Spring Boot. Could you please create that issue in the Spring Framework issue tracker?

Comment From: bclozel

This is an issue in the sense that ContentCachingRequestWrapper works differently than what you'd like. But it works as advertized. Javadoc says:

/*
 * {@link javax.servlet.http.HttpServletRequest} wrapper that caches all content read from
 * the {@linkplain #getInputStream() input stream} and {@linkplain #getReader() reader},
 * and allows this content to be retrieved via a {@link #getContentAsByteArray() byte array}.

ContentCachingR*Wrapper aren't meant to be general purpose wrappers for all filters; you can reuse those in your own Servlet filters, but they might not work for your use case.

Comment From: ivanhjc

I've spent more than 4 hours and still couldn't get this to work. As the OP stated here it's a frequently-requested problem. I've tried many solutions suggested here, here, and here, but none of them work. Do I need to go through the official documentation to find the answer myself?

Comment From: tinnapat

As a spring boot user who tries using this class before, I understand that there is nowhere in the documentation saying that ContentCachingRequestWrapper allow request to be read more than once. As describe in javadoc, the request body can still be read only once using getInputStream or getReader but after one of these methods are called, you can read the cache request again many time using method getContentAsByteArray but you can not read request using either getInputStream or getReader again.

And also you can not call getContentAsByteArray until either getInputStream or getReader is called.

Comment From: jamietanna

FYI I've documented this at https://www.jvt.me/posts/2020/05/25/read-servlet-request-body-multiple/ based on https://stackoverflow.com/a/36619972/2257038 and https://stackoverflow.com/a/30748533/2257038 - this caches the actual ServletInputStream rather than just the bytes that are returned.

(Originally published at: https://www.jvt.me/mf2/2020/05/wzavv/)

Comment From: jamietanna

As mentioned in my article above, I've also released a library to Maven Central to wrap this functionality for you, at the following coordinates:

<groupId>me.jvt.multireadservlet</groupId>
<artifactId>multiple-read-servlet</artifactId>
<version>4.0.1</version>

(Originally published at: https://www.jvt.me/mf2/2021/01/rhtpa/)