使用 ContentCachingRequestWrapper 后缺少必需的请求正文

Its*_*has 7 java filtering http spring-boot

我需要读取我的GenericFilterBean. 因为我不能两次调用getreader我用过ContentCachingRequestWrapper类似 -

HttpServletRequest httpRequest = (HttpServletRequest) request;
ContentCachingRequestWrapper cachedRequest = new ContentCachingRequestWrapper(httpRequest);
Run Code Online (Sandbox Code Playgroud)

获取请求正文-

String payload = cachedRequest.getReader().lines().collect(Collectors.joining());
Run Code Online (Sandbox Code Playgroud)

并链接请求-

chain.doFilter(cachedRequest, response);
Run Code Online (Sandbox Code Playgroud)

但我的控制器仍然抛出-

 .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by handler execution: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public org.springframework.http.ResponseEntity<?> com.siemens.plm.it.sf.api.controllers.OrderController.createCCOrder(com.siemens.plm.it.de.ms.provisioning.model.sap.SapQuoteCreationArgument,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
Run Code Online (Sandbox Code Playgroud)

如何链接请求以便我也可以读取控制器中的有效负载?

小智 7

我遇到了同样的问题。您需要在 requestWrapper 上调用 getInputStream 才能让它被缓存。您的过滤器应如下所示:

@Component
public class CachingRequestBodyFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
            throws IOException, ServletException {
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper((HttpServletRequest) servletRequest);

        //this line is necessary to cache InputStream
        wrappedRequest.getInputStream();
        //String requestBody = IOUtils.toString(wrappedRequest.getInputStream(), StandardCharsets.UTF_8); with this line you can map requestBody to String


        chain.doFilter(wrappedRequest, servletResponse);
    }
}
Run Code Online (Sandbox Code Playgroud)

控制器:

@PostMapping(ENDPOINT)
    void endpoint(HttpServletRequest request) {
        ContentCachingRequestWrapper requestWrapper = (ContentCachingRequestWrapper) request;
        String requestBody = new String(requestWrapper.getContentAsByteArray());
        //process requestBody
}
Run Code Online (Sandbox Code Playgroud)


Fur*_*med -1

我认为通过这样做:

String payload = cachedRequest.getReader().lines().collect(Collectors.joining());
Run Code Online (Sandbox Code Playgroud)

你做错了。

尝试这个 :

String input = ByteSource.wrap(cachedRequest.getContentAsByteArray())
    .asCharSource(StandardCharsets.UTF_8).read();
Run Code Online (Sandbox Code Playgroud)

正如文档所示:

缓存从输入流和读取器读取的所有内容,并允许通过字节数组检索该内容

一些有用的链接: 链接 1链接 2