Jetty 8 GzipFilter有时不适用

时间:2011-09-22 11:21:21

标签: java servlets jetty servlet-filters

我刚刚将我的网络服务器从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异常。那是为什么?

3 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,并找到了2个原因:

  1. 如果您的任何servlet过早地调用了response.getWriter()。flush(),GZipFilter将无法正常工作。在我的例子中,Spring MVC和Sitemesh中的Freemarker都是这样做的,所以我必须为Freemarker servlet和Spring MVC Freemarker配置对象设置Freemarker设置“auto_flush”为“false”。
  2. 如果您使用普通的GzipFilter,由于某种原因,它不允许您在Jetty的“包含”阶段设置任何标题。所以我不得不使用IncludableGzipFilter代替。
  3. 我做了这些修改后,对我有用。希望对你有所帮助。

答案 1 :(得分:0)

我建议您使用Fiddler跟踪您的HTTP请求吗?

也许,像Last-Modified这样的标头向您的浏览器表明您的请求/test/hello_world?param=test的内容仍然相同...所以您的浏览器会重复使用其缓存中的内容,只需关闭请求,没有阅读其内容......

两个不同的请求会发生什么?

  • /test/hello_world?param=test
  • /test/hello_world?param=test&foo=1

答案 2 :(得分:0)

您可以使用其他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);

我遇到了同样的问题,这解决了这个问题。