【问题标题】:HttpServletRequest reading large post body - unable to read all data, wait for all chunksHttpServletRequest 读取大型帖子正文 - 无法读取所有数据,等待所有块
【发布时间】:2019-07-26 08:10:57
【问题描述】:

当我读到这样的数据时

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

【问题讨论】:

  • 您可以尝试使用IOUtils.readFully() 方法之一将数据读入Buffer 或数组,然后将结果转换为String
  • 你要读取什么数据?
  • @ScaryWombat 它是一个 JSON 对象
  • @JohnBollinger 我将 char[] 的大小设置为什么?如果我将它设置为内容长度,我会报错java.io.EOFException: Length to read: 11912 actual: 8129 我认为块大小是 8129
  • @SumamaWaheed,内容长度给出了 bytes 的长度,而不是字符。 (编码)字符的数量不一定相同。目前尚不清楚是否可以通过此路线获得解决方案,但如果是,那么您可能应该将content-length bytes 读入字节数组,然后将结果转换为String 根据到客户端指定的编码,或者根据相应的网络协议的默认编码,不一定是Java的默认编码。

标签: java apache http tomcat servlets


【解决方案1】:

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

IOUtils.toString(request.getInputStream());

从@John Bollinger 的评论中发布答案

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

【讨论】:

    猜你喜欢
    • 2017-01-10
    • 2020-08-15
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 2018-08-02
    相关资源
    最近更新 更多