ContentCachingRequestWrapper

ContentCachingRequestWrapper

我实现了一个过滤器,在该过滤器中,我想先读取请求的内容以进行一些检查,然后再继续。

但是问题在于,在以下来自过滤器链的过滤器中,调用了getParameters()class Request (org.eclipse.jetty.server.Request)方法,而不是getParameters()class ContentCachingRequestWrapper方法。因此,parametersMap未填充,并且始终为空。

这是我的代码的样子:

@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);
}
}

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

在控制器中,参数映射始终为空。
如果我没有在过滤器中调用servletRequest.getInputStream(),则将填充参数Map。

我正在使用将Jetty作为应用程序服务器的Spring Boot 1.5.6

最佳答案

ContentCachingRequestWrapper不能那样工作,并且有一些限制。据我记得,只有POST请求和内容类型应该是application/x-www-form-urlencoded。如果这适合您,这是您应该做的:

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!!

希望这可以帮助。

09-27 19:43