6

I have implemented a Filter, in which I want to read the content of request first for some checks and then I would like to go on.

But the problem is, that in the following filter from the filter chain the getParameters() Method from class Request (org.eclipse.jetty.server.Request) is called and not the getParameters() method from class ContentCachingRequestWrapper. So the parametersMap are not filled and is always empty.

Here is how my code looks like:

@Component
@Order(1)
public class EncodingFilter extends GenericFilterBean {

private static final Logger LOG = 
LoggerFactory.getLogger(EncodingFilter.class);

@Override
public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException {

final HttpServletRequest req = (HttpServletRequest) request;
HttpServletRequest servletRequest = new ContentCachingRequestWrapper(req);

String read = ByteSource.wrap(ByteStreams.toByteArray(servletRequest.getInputStream()))
        .asCharSource(StandardCharsets.UTF_8).read();
// Doing analysis .....
// last step call filter chain
chain.doFilter(servletRequest, response);
}
}

And in Controller:

@PostMapping(
    value = Endpoints.Janus.INIT,
    produces = MediaType.TEXT_HTML_VALUE
)
public ModelAndView controller(
    @RequestParam LinkedCaseInsensitiveMap<String> params,
    HttpServletRequest servletRequest
) {
 ....  
}

In the controller the params Map is always empty. If I don't call servletRequest.getInputStream() in my filter, the params Map is filled.

I am working with Spring Boot 1.5.6 with Jetty as Application Server

Michael Kronberger
  • 93
  • 1
  • 2
  • 12

2 Answers2

15

ContentCachingRequestWrapper doesnt work that way and has some limitations. Only POST request and content type should be application/x-www-form-urlencoded as far as I remember. If this fits for you, here's what you should do:

final HttpServletRequest req = (HttpServletRequest) request;
HttpServletRequest servletRequest = new ContentCachingRequestWrapper(req);
servletRequest.getParameterMap(); // needed for caching!!

String read = ByteSource.wrap(servletRequest.getContentAsByteArray())
    .asCharSource(StandardCharsets.UTF_8).read(); // Please note that we're not touching input stream!!

Hope this helps.

Leffchik
  • 1,950
  • 14
  • 16
  • Thx a lot. This was the solution – Michael Kronberger Mar 13 '18 at 09:09
  • @MichaelKronberger, please, accept this answer if it was helpful. Thanks in advance – Leffchik Mar 13 '18 at 09:19
  • Nicely explained! upvoting the answer! – VijayD Mar 13 '18 at 09:20
  • Note: `multipart/form-data` is also relevant to `request.getParameter` calls **and** the multipart `request.getPart` methods. – Joakim Erdfelt Mar 13 '18 at 14:36
  • 3
    What is ByteSource ? – Rohit Salecha Feb 14 '20 at 09:45
  • 1
    Its from com.google.guava, add it in your pom.xml from Maven Repository to use ByteSource. – Thiago Prochnow Nov 26 '21 at 12:27
  • This answer looks ok, but not working as I do not know how to test from postman. I have encrypted data, and want to decrypt inside the interceptor. If I use radio button - application/x-www-form-urlencoded it aske me key value pair. But I only know I was sending body. My controller looks like - public String saveData(@RequestBody String qWith, @RequestAttribute("customAttribute") Book customAttribute) .. In the interceptor I was decypting and setting customattribute with decrypted value. How can I resolve my problem using www-form-urlencoded . I have to invoke this from Angular too – Kris Swat Dec 01 '21 at 23:13
  • Perfect, you can't use ContentCachingRequestWrapper for application/json content type. – Amare Aug 25 '22 at 15:19
0

Please try the two proposed solutions mentioned below:
1. HttpServletRequestWrapper servletRequest = new ContentCachingRequestWrapper(req);
OR
2. ContentCachingRequestWrapper servletRequest = new ContentCachingRequestWrapper(req);
Instead of HttpServletRequest servletRequest = new ContentCachingRequestWrapper(req);
As you can check here that ContentCachingRequestWrapper class extends HttpServletRequestWrapper which extends ServletRequestWrapper and implements HttpServletRequest.
So here by performing upcasting, you are may be facing this issue. Please check and let me know if this is not the case, then I will debug it further.

VijayD
  • 826
  • 1
  • 11
  • 33