使用tomcat servlet上的服务器发送事件对gzip / deflate进行压缩

时间:2018-10-23 09:59:33

标签: java tomcat gzip server-sent-events deflate

我正在使用服务器发送的事件进行流式响应(文本/事件流)。我们想使用gzip或deflate压缩来压缩响应,但是浏览器显示:ERR_CONTENT_DECODING_FAILED。 相同的代码-

response.setContentType("text/event-stream; charset=UTF-8");
response.addHeader("Connection", "keep-alive");
response.addHeader("Cache-Control", "no-cache, must-revalidate");
response.addHeader("Content-Encoding", "deflate");
PrintWriter writer = response.getWriter();
number = 10;
time = 100;
for (int i = 0; i < number; i++) {
  String resp = "data: " + "Some Response" + "\r\n";

  Deflater deflater = new Deflater(Deflater.DEFLATED);
  byte[] input = resp.getBytes("UTF-8");
  deflater.setInput(input);
  deflater.finish();
  byte[] output = new byte[1024];
  deflater.deflate(output);
  deflater.end();
  writer.write(new String(output, "UTF-8"));
  writer.flush();
  try {
    Thread.sleep(time);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
}
String resp = "data: close\r\n";
Deflater deflater = new Deflater(Deflater.DEFLATED);
byte[] input = resp.getBytes("UTF-8");
deflater.setInput(input);
deflater.finish();
byte[] output = new byte[1024];
deflater.deflate(output);
deflater.end();
writer.write(new String(output, "UTF-8"));
writer.flush();

2 个答案:

答案 0 :(得分:0)

  1. 压缩流是二进制数据。不得使用response.getWriter()打印。请改用response.getOutputStream()

更新

  

Shiva Bhalla:在显示第一段响应后,将response.getOutputStream()与text / event-stream一起使用不能进行正确的流传输,该请求在浏览器中失败了。

  1. 您必须使用单个Deflater实例压缩整个流。

    在代码中,您分别压缩每个片段。这等效于以下内容:

    • 您需要一系列文本文件(01.txt,02.txt ...)。
    • 您将每个压缩到一个gzip存档中。 (01.txt.gz,02.txt.gz,...)
    • 您将档案串联到一个文件中。

    以上内容产生了错误的存档。 Gzip文件不能这样连接。正确的代码应执行以下操作:

    • 您需要一系列文本文件(01.txt,02.txt ...)。
    • 您将文本文件串联为一个文件(text.txt)。
    • 您将文件压缩为gzip存档。 (text.txt.gz)
  2. 我建议您使用java.util.zip.DeflaterOutputStream (1)而不是直接使用Deflater。例如

    new DeflaterOutputStream(response.getOutputStream(), true);
    
  3. 当心引入了BREACH漏洞。

答案 1 :(得分:0)

在连接器属性中将“ text / event-stream; charset = UTF-8,ms-stream; charset = UTF-8”添加为“ compressableMimeType”即可!