您可以添加过滤器,拦截电流并将其包装在自定义中。在自定义 中,读取请求正文并对其进行缓存,然后实现并从缓存的值中读取。由于在包装请求后,缓存的值始终存在,因此您可以多次读取请求正文:HttpServletRequest
HttpServletRequestWrapper
HttpServletRequestWrapper
getInputStream
getReader
@Component
public class CachingRequestBodyFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest currentRequest = (HttpServletRequest) servletRequest;
MultipleReadHttpRequest wrappedRequest = new MultipleReadHttpRequest(currentRequest);
chain.doFilter(wrappedRequest, servletResponse);
}
}
在此过滤器之后,每个人都会看到哪些具有多次读取功能的功能:wrappedRequest
public class MultipleReadHttpRequest extends HttpServletRequestWrapper {
private ByteArrayOutputStream cachedContent;
public MultipleReadHttpRequest(HttpServletRequest request) throws IOException {
// Read the request body and populate the cachedContent
}
@Override
public ServletInputStream getInputStream() throws IOException {
// Create input stream from cachedContent
// and return it
}
@Override
public BufferedReader getReader() throws IOException {
// Create a reader from cachedContent
// and return it
}
}
为了实现,你可以从spring框架中查看ContentCachingRequestWrapper
,它基本上做同样的事情。MultipleReadHttpRequest
这种方法有其自身的缺点。首先,它有点低效,因为对于每个请求,请求正文至少被读取两次。另一个重要的缺点是,如果你的请求正文包含值得的流,你会读取这些数据,更糟糕的是,它会把它放到内存中以供进一步检查。10 GB
10 GB