繁体   English   中英

Jetty-servlets GzipFilter不适用于Jetty 9.2.7.v20150116和Spring

[英]Jetty-servlets GzipFilter doesn't work with Jetty 9.2.7.v20150116 and Spring

我在web.xml -file中使用以下xml将GzipFilter配置为与Jetty一起运行的Spring应用程序。 在Chrome中使用开发人员工具进行检查时,我希望资源的大小会变小,并且响应头中的“编码”值也应该为“ gzip”。 但是,这些都不是可见的。

但是,当在我的IDE中使用调试工具进行检查时,我注意到过滤器已应用(我将断点放置在GzipFilter上),并且在使用开发人员工具进行检查时,我还注意到etag-header在响应中具有-gzip扩展名。 但是,内容似乎没有压缩。

我的想法不多了,不胜感激。

<filter>
  <filter-name>GzipFilter</filter-name>
  <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
  <init-param>
     <param-name>mimeTypes</param-name>
     <param-value>text/html,text/plain,text/xml,application/xhtml+xml,text/css,application/javascript,application/json,image/svg+xml</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>GzipFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

编辑:添加请求和响应头

 Request:
 GET ******* HTTP/1.1
 Host: localhost:8081
 Connection: keep-alive
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6)       AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
 Accept: */*
 Referer: http://localhost:8081/
 Accept-Encoding: gzip, deflate, sdch
 Accept-Language: en-US,en;q=0.8,fi;q=0.6
 Cookie: XSRF-TOKEN=******; JSESSIONID=*******

 Response:
 HTTP/1.1 200 OK
 Date: Mon, 29 Aug 2016 13:59:59 GMT
 Cache-Control: public
 Date: Mon, 29 Aug 2016 13:59:59 GMT
 Content-Type: application/javascript;charset=UTF-8
 Vary: Accept-Encoding, User-Agent
 ETag: "0f93db3b42f19c57f4a216dd80f63bae5--gzip"
 Server: Jetty(9.2.7.v20150116)
 Transfer-Encoding: chunked

ETag上的--gzip后缀由GzipFilter使用,以了解请求处理是否实际上通过GzipFilter

目的是如果请求曾经被压缩,现在不再被压缩,则将破坏DefaultServletETag支持。

含义如下:

  • 使用gzip配置的服务器
  • 请求资源/foo.js
  • DefaultServlet使用ETag: abcdef将响应发送到/foo.js
  • GzipFilter配置为压缩application/javascript ,因此它压缩了响应并将ETag更改为ETag: abcdef--gzip
  • 一段时间后,重新配置了GzipFilter(不同的url模式,不同的mime类型,等等)
  • 相同的User-Agent请求带有ETag: abcdef--gzip资源/foo.js ,但这不再通过GzipFilter进行,因此DefaultServlet将无法识别ETag并重新提供内容。

至于为什么不压缩您的内容,可能是由于您设置response.setContentType()还是响应主体内容的大小所致。

首先,您需要确保访问响应输出流(或编写器) 之前始终设置响应状态代码,响应标头和(可选)响应缓冲区大小,因为.getOutputStream().getWriter()都使用响应对象中的值进行设置。

GzipFilter还使用这些值来知道是否应压缩响应。

接下来,响应主体内容的大小很重要,因为在涉及GzipFilter之前,响应大小有一个下限。 (它实际上无法有效地压缩GzipFilter.minGzipSize以下的大多数内容)

在您的Jetty版本中,我相信minGzipSize是256个字节。

由于您粘贴的响应标头没有Content-LengthTransfer-Encoding: chunked ,因此我无法确定您的响应实际有多大。

重要的升级说明:Jetty 9.3+中的GzipFilter已被完全弃用,如果使用,将导致无操作。 这是因为在使用Servlet 3.1和异步I / O时,用于Gzip压缩的过滤器方法存在很大问题。

Jetty 9.3+中的Gzip支持已移出Servlet规范,并移至较低级别的HttpOutput.Interceptor模式,该模式仅在发生刷新(指定内部自动或应用程序)后才压缩内容。

换句话说,servlet缓冲区在从应用程序写入servlet缓冲区时不会被压缩,就像在Jetty 9.2及之前的版本中一样。 相反,仅当它们离开servlet缓冲区并进入网络级写入时才压缩它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM