java.lang.IllegalStateException: getReader() 已为当前请求调用后无法调用 getInputStream()
java.lang.IllegalStateException: Cannot call getInputStream() after getReader() has already been called for the current request
我写了拦截器:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("[pre-handle] method: {}\tURL: {}", request.getMethod(), request.getRequestURL());
if (HttpMethod.POST.name().equals(request.getMethod())) {
log.info(request.getReader().lines().collect(Collectors.joining()));
}
return true;
}
但是当我尝试调用控制器时,抛出异常:
java.lang.IllegalStateException: Cannot call getInputStream() after
getReader() has already been called for the current request
据我了解,调用 getReader() 会关闭 InputStream 并且控制器不会收到任何内容。
如何解决?
要多次读取请求,您需要在第一次读取之前缓存您的请求。更多信息可以阅读 here.
Spring MVC 提供了 ContentCachingRequestWrapper class。
它是原始 HttpServletRequest 对象的包装器。
要使用它,我们必须首先创建一个包装原始 HttpServletRequest 的 Web 过滤器:
@Component
public class CachingRequestBodyFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest currentRequest = (HttpServletRequest) servletRequest;
ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(currentRequest);
chain.doFilter(wrappedRequest, servletResponse);
}
之后你可以在你的拦截器中使用ContentCachingRequestWrapper的getContentAsByteArray方法获取byte[]内容
我写了拦截器:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("[pre-handle] method: {}\tURL: {}", request.getMethod(), request.getRequestURL());
if (HttpMethod.POST.name().equals(request.getMethod())) {
log.info(request.getReader().lines().collect(Collectors.joining()));
}
return true;
}
但是当我尝试调用控制器时,抛出异常:
java.lang.IllegalStateException: Cannot call getInputStream() after getReader() has already been called for the current request
据我了解,调用 getReader() 会关闭 InputStream 并且控制器不会收到任何内容。 如何解决?
要多次读取请求,您需要在第一次读取之前缓存您的请求。更多信息可以阅读 here.
Spring MVC 提供了 ContentCachingRequestWrapper class。 它是原始 HttpServletRequest 对象的包装器。
要使用它,我们必须首先创建一个包装原始 HttpServletRequest 的 Web 过滤器:
@Component
public class CachingRequestBodyFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest currentRequest = (HttpServletRequest) servletRequest;
ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(currentRequest);
chain.doFilter(wrappedRequest, servletResponse);
}
之后你可以在你的拦截器中使用ContentCachingRequestWrapper的getContentAsByteArray方法获取byte[]内容