如何在gzip标头之后在Spark Java中正确设置content-length

时间:2019-06-01 07:50:57

标签: java http-headers gzip spark-java

我正在使用Spark来提供不同类型的内容。 “ Content-Length”的计算正确,但是在使用时遇到了一个问题:

response.header("Content-Encoding", "gzip")

根据their documentation,当设置了标头时,spark会自动gzip内容...并且做到了。

但是,我之前计算的“内容长度”不再有效,因此在浏览器中出现“ net :: ERR_CONTENT_LENGTH_MISMATCH”错误。

我自己将其压缩,并无法计算出最终的大小,因为spark会再次压缩输出。

如何知道火花压缩输出后的结果尺寸是多少?

1 个答案:

答案 0 :(得分:0)

感谢您的澄清!

  1. 是的,现在您要手动添加它,这就是我要做的,并保持这种方式,除非您确实需要用例Content-Length。不知道大小有点烦人,但并不罕见。
  2. 我很确定使用当前spark的内部API很难做到这一点。我昨天玩了一下,用apache commons CountingOutputStream截取了OutputStreams,并且没有API可以在不更改代码的情况下做到这一点,并且它还有其他问题。问题还在于,在火花压缩输出之后,很有可能已经将其刷新发送并发送回客户端,但是必须在发送数据之前发送此标头。在发送数据之前,您基本上必须了解这一点,因此这是最困难的方法。
  3. 是的,最容易实现的方法可能是将他已经准备好的压缩数据作为ByteArray(似乎您正在使用kotlin)来提供,并禁用自动压缩。 ByteArrayOutputStream是个不错的选择。这样至少可以压缩一次。还有一些关于设置Content-Encoding报头,同时强制spark不进行编码的事情,但这很容易打补丁。丑陋的事情是,您必须将整个数据存储在内存中,服务器不会在开始所有计算之前就开始发送数据,因此用户单击下载和开始下载之间会有延迟。
  4. 如果大文件将被多次使用,则可以提前或在首次运行时预先计算它们的gzip压缩大小并缓存该信息。这样,您可以将数据直接发送到流中,并且一开始就知道信息。