Jetty 8 GzipFilter 有时不适用
Posted
技术标签:
【中文标题】Jetty 8 GzipFilter 有时不适用【英文标题】:Jetty 8 GzipFilter does not apply sometimes 【发布时间】:2011-11-22 18:10:10 【问题描述】:我刚刚将我的网络服务器从 Jetty 6.x 更新到 Jetty 8.0.1,出于某种原因,当我执行完全相同的请求时,有时响应已被 Gzip 压缩,有时则没有。
下面是 servlet 的 service() 方法开头的请求和响应的样子:
Request: [GET /test/hello_world?param=test]@11538114 org.eclipse.jetty.server.Request@b00ec2
Response: org.eclipse.jetty.servlets.GzipFilter$2@1220fd1
WORKED!
Request:[GET /test/hello_world?param=test]@19386718 org.eclipse.jetty.server.Request@127d15e
Response:HTTP/1.1 200
Connection: close
FAILED!
这是我的 GzipFilter 声明:
EnumSet<DispatcherType> all = EnumSet.of(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.FORWARD,
DispatcherType.INCLUDE, DispatcherType.REQUEST);
FilterHolder gzipFilter = new FilterHolder(new GzipFilter());
gzipFilter.setInitParameter("mimeTypes", "text/javascript");
gzipFilter.setInitParameter("minGzipSize", "0");
context.addFilter(gzipFilter, "/test/*", all);
Javadoc 说:
GZIP Filter This filter will gzip the content of a response if:
The filter is mapped to a matching path ==>
The response status code is >=200 and <300
The content length is unknown or more than the minGzipSize initParameter or the minGzipSize is 0(default)
The content-type is in the comma separated list of mimeTypes set in the mimeTypes initParameter or if no mimeTypes are defined the content-type is not "application/gzip"
No content-encoding is specified by the resource
在我看来,所有这些条件都满足,除了最后一个“资源未指定内容编码”。如何验证?
另外,出于我也忽略的原因,当未使用 GzipFilter 过滤响应时,response.getWriter() 会引发 IO 异常。这是为什么呢?
【问题讨论】:
【参考方案1】:我遇到了同样的问题,找到了2个原因:
-
如果您的任何 servlet 过早调用 response.getWriter().flush(),GZipFilter 将无法工作。在我的例子中,Spring MVC 中的 Freemarker 和 Sitemesh 都在这样做,因此我必须将 Freemarker servlet 和 Spring MVC Freemarker 配置对象的 Freemarker 设置“auto_flush”设置为“false”。
如果您使用普通的 GzipFilter,由于某种原因,它不允许您在 Jetty 的“包含”阶段设置任何标题。所以我不得不改用IncludableGzipFilter。
进行这些更改后,它对我有用。希望对你也有帮助。
【讨论】:
【参考方案2】:您可以使用另一个 GzipFilter。将其添加到您的 maven 或下载 jar 文件http://mvnrepository.com/artifact/net.sourceforge.pjl-comp-filter/pjl-comp-filter/1.7
然后只需更改您的代码:
EnumSet<DispatcherType> all = EnumSet.of(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
FilterHolder gzipFilter = new FilterHolder(new CompressingFilter());
gzipFilter.setInitParameter("includeContentTypes", "text/javascript");
context.addFilter(gzipFilter, "/test/*", all);
我遇到了同样的问题,这解决了问题。
【讨论】:
【参考方案3】:我可以建议您使用Fiddler 来跟踪您的 HTTP 请求吗?
也许,像Last-Modified
这样的标头向您的浏览器表明您的请求内容/test/hello_world?param=test
仍然相同...因此您的浏览器会重用缓存中的内容并简单地关闭请求,而不读取其内容...
两个不同的请求会发生什么?
/test/hello_world?param=test
/test/hello_world?param=test&foo=1
【讨论】:
以上是关于Jetty 8 GzipFilter 有时不适用的主要内容,如果未能解决你的问题,请参考以下文章
使用maven jetty插件在java 8上运行jetty 9时出现错误扫描文件[重复]
jetty 支持内嵌ssh项目吗,为啥在tomcat下面正常的war 放到jetty就跑不起来