HttpServletRequest读取较大的帖子正文-无法读取所有数据,等待所有块

时间:2019-03-04 23:06:14

标签: java apache http tomcat servlets

当我读取这样的数据时

    String body = null;

    try {
        body = IOUtils.toString(request.getReader());
    } catch (IOException e) {
        //
    }

并非所有数据都被读取。 “ content-length”标头包含正确的数据长度,但是看起来IOUtils.toString并不等待所有的块。

这个旧的冗长代码有效,但是我想知道是否有一种现代的方法可以等到所有数据都被读取:

    String body = null; 
            try {
                ServletInputStream in = request.getInputStream();
                String reqLengthString = request.getHeader("content-length");
                int requestLength = 0;

                try {
                    requestLength = Integer.valueOf(reqLengthString).intValue();
                } catch (Exception e) {
                    return doForecastErrorResponse(response,"Invalid Content Length");
                }
                Debug.logInfo("RequestLength: "+requestLength, MODULE);

                int i = -1;
                while (requestLength > 0) {
                    byte[] line = new byte[8192];
                    i = waitingReadLine(in, line, 0, 8192, requestLength);
                    requestLength -= i;
                    if (Debug.verboseOn()) {
                        Debug.logVerbose("remaining request length: "+requestLength, MODULE);
                        Debug.logVerbose("data this grab: "+new String(line), MODULE);
                    }

                    jb.append(new String(line));
                }

                body = jb.toString().trim();
                if (Debug.verboseOn()) {
                    Debug.logVerbose("String: "+body, MODULE);
                }

            } catch (IOException e) {
                return doForecastErrorResponse(response,"Error reading input."+e.getMessage());

            }


private static int waitingReadLine(ServletInputStream in, byte[] buf, int off, int len, int reqLen) throws IOException {
        int i = -1;

        while (((i = in.readLine(buf, off, len)) == -1) && (reqLen > 0)) {
            int waitCount = 0;
            int MAX_WAITS = 30;
            int WAIT_INTERVAL = 1000;

            if (Debug.verboseOn()) Debug.logVerbose("Waiting for read line", MODULE);
            if (waitCount > MAX_WAITS) {
                if (Debug.verboseOn()) Debug.logVerbose("Waited " + waitCount + " times, bailing out while still expecting " + reqLen + " bytes.", MODULE);
                throw new IOException("waited " + waitCount + " times, bailing out while still expecting " +
                        reqLen + " bytes.");
            }
            waitCount++;
            long endMS = new Date().getTime() + WAIT_INTERVAL;

            while (endMS > (new Date().getTime())) {
                try {
                    Thread.sleep(WAIT_INTERVAL);
                } catch (Exception e3) {
                    if (Debug.verboseOn()) Debug.logVerbose("Exception waiting for read line"+ e3.getMessage(), MODULE);
                }
            }
            if (Debug.verboseOn()) Debug.logVerbose("Waited " + (new Date().getTime() - (endMS - WAIT_INTERVAL)) + " ms", MODULE);
        }
        return i;
    }

1 个答案:

答案 0 :(得分:0)

更新:实际上,诀窍是使用getInputStream而不是getReader

IOUtils.toString(request.getInputStream());

通过@John Bollinger发表评论中的答案

    byte[] buffer = new byte[requestLength];
    IOUtils.readFully(request.getInputStream(), buffer);
    body = new String(buffer);