首页 > 解决方案 > SpringMvc host 通过 request.getInputStream 获取请求数据时有时会花费太多时间

问题描述

在SpringMvc中,有时工作线程在获取请求数据时会被阻塞并托管太多时间(10s-60s)request.getInputStream。但通常它运行良好。从调试日志中,我找到了所有主机的时间bufferedReader.read,以及请求正文不是太大。

环境:

代码如下:

    public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
        @Autowired
        private Logger logger = LoggerFactory.getLogger(this.getClass());

        private final String body;

        public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            StringBuilder stringBuilder = new StringBuilder();
            BufferedReader bufferedReader = null;
            try {
                InputStream inputStream = request.getInputStream();
                if (inputStream != null) {
                    bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                    char[] charBuffer = new char[128];
                    int bytesRead = -1;
                    while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                        stringBuilder.append(charBuffer, 0, bytesRead);
                    }
                } else {
                    stringBuilder.append("");
                }
            } catch (IOException ex) {
                throw ex;
            } finally {
                if (bufferedReader != null) {
                    try {
                        bufferedReader.close();
                    } catch (IOException ex) {
                        logger.error("close bufferedReader exception, detail:", ex);
                    }
                }
            }
            body = stringBuilder.toString();
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {
            final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
            ServletInputStream servletInputStream = new ServletInputStream() {
                @Override
                public boolean isFinished() {
                    return false;
                }

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

                @Override
                public void setReadListener(ReadListener readListener) {

                }

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

        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(this.getInputStream()));
        }

        public String getBody() {
            return this.body;
        }
    }

标签: springspring-bootspring-mvctomcatserversocket

解决方案


推荐阅读