【问题标题】:PlayWS calculate the size of a http call without consuming the streamPlayWS 在不消耗流的情况下计算 http 调用的大小
【发布时间】:2017-12-16 01:22:05
【问题描述】:

我目前正在使用返回 Akka 流的 PlayWS http 客户端。据我了解,我可以使用流并将其转换为 Byte[] 来计算大小。但是,这也会消耗流,我不能再使用它了。反正围绕这个?

【问题讨论】:

  • 你也许可以使用 HEAD 请求方法来检索内容长度,这就是流的工作方式,除非你全部消费,否则你无法知道有多少元素。

标签: scala playframework akka


【解决方案1】:

我认为这个问题有两个不同的方面。

  1. 您想提前知道服务器响应的大小以准备缓冲区。不幸的是,没有保证的方法可以做到这一点。当服务器通过chunked transfer encoding 事先不知道响应的大小时,HTTP 1.1 规范明确允许传输模式。另见3.3.1. Transfer-Encoding的引用:

接收者必须能够解析分块传输编码 (第 4.1 节),因为它在构建信息中起着至关重要的作用 当预先不知道有效载荷主体大小时。

3.3.3. Message Body Length 部分指定了消息正文的长度是如何定义的,除了前面提到的分块传输编码之外,它还包含非常无用的内容

  1. 否则,这是没有声明消息的响应消息 正文长度,因此消息正文长度由 在服务器关闭之前收到的八位字节数 连接。

这是为了向后兼容而添加的,不鼓励使用,但仍然是法律允许的。

在许多现实世界的场景中,您仍然可以使用服务器可能返回的Content-Length 标头字段。但是这里也有一个问题:如果使用gzip Content-Encoding,那么Content-Length 将包含压缩体的大小。

总结一下:一般情况下,在完全获得服务器响应之前,您无法提前获得消息正文的大小,即在代码方面对响应执行阻塞调用。您可以尝试使用Content-Length,它可能对您的具体情况有所帮助,也可能没有帮助。

  1. 您已经有一个完全下载的响应(或者您可以阻止StreamedResponse)并且您希望通过首先获取大小然后再处理实际数据来处理它。在这种情况下,您可以首先使用getBodyAsBytes 方法,该方法返回IndexedSeq[Byte],因此具有size,然后使用Source.single 将其转换为新的Source,这实际上正是默认值(即非流式传输) getBodyAsSource 的实现。

【讨论】:

    猜你喜欢
    • 2017-09-10
    • 2012-05-07
    • 2015-10-19
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    相关资源
    最近更新 更多