Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法正确读取拦截器-Spring BOOT 2.0.4中的请求正文_Java_Spring_Rest_Spring Boot_Interceptor - Fatal编程技术网

Java 无法正确读取拦截器-Spring BOOT 2.0.4中的请求正文

Java 无法正确读取拦截器-Spring BOOT 2.0.4中的请求正文,java,spring,rest,spring-boot,interceptor,Java,Spring,Rest,Spring Boot,Interceptor,我在侦听器中读取请求正文时遇到问题。getReader和getInputStream都会导致问题。 我的拦截器: public class MyInterceptor extends HandlerInterceptorAdapter { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exceptio

我在侦听器中读取请求正文时遇到问题。getReader和getInputStream都会导致问题。 我的拦截器:

public class MyInterceptor extends HandlerInterceptorAdapter {
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception)
        throws Exception {
    // TODO Auto-generated method stub

}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
        throws Exception {
    // TODO Auto-generated method stub
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    String requestBody = httpRequest.getReader().lines().collect(Collectors.joining(System.lineSeparator()));

//or
// String requestBody = new BufferedReader(new InputStreamReader(httpRequest.getInputStream()))
//                .lines().collect(Collectors.joining("\n"));
//some logic...
    return true;
}
这两种方法都失败了,因为spring可能在内部某处使用了这样的资源。 第一个原因java.lang.IllegalStateException:已为此请求调用getReader,缺少其他必需的请求正文:org.springframework.http.ResponseEntity

我尝试了一些使用包装器的变通方法,但没有效果。我想这是因为我不能像过滤器一样传递包装器。我不想使用过滤器,因为我有一个常见的异常managager@ControllerAdvice.


这是一个已知的问题吗?有什么解决办法吗?

最后我终于找到了答案,所以我将在这里为其他人留下一些简单但有用的建议。 我使用了一个请求包装器,但为了使其正常工作,我添加了一个具有最高顺序的过滤器,以便在执行拦截器之前,在开始时将每个请求包装到包装器中。现在它运行良好; 下面是最重要的代码-将每个请求包装到多读包装器中的过滤器拦截器看起来与上面几乎相同,包装器不是我发明的,是在堆栈上发现的,我发现它是最清晰可读的:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class GlobalWrapFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    MultiReadRequest wrapper = new MultiReadRequest((HttpServletRequest) request);
    chain.doFilter(wrapper, response);
}

@Override
public void destroy() {
}

class MultiReadRequest extends HttpServletRequestWrapper {

    private String requestBody;

    public MultiReadRequest(HttpServletRequest request) {
        super(request);
        try {
            requestBody = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody.getBytes());
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return byteArrayInputStream.available() == 0;
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream(), Charset.forName("UTF-8")));
    }
}
}