【问题标题】:Setup Jetty GzipHandler programmatically以编程方式设置 Jetty GzipHandler
【发布时间】:2014-08-22 16:08:00
【问题描述】:

我在玩 Jetty GzipHandler,它的工作似乎很奇怪:它只压缩已经压缩的文件。

我的整个设置是

GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setHandler(myHandler);
server.setHandler(gzipHandler);

浏览器(Chromium)总是发送一个包含

的标头
Accept-Encoding:gzip,deflate,sdch

所以根据文档

GZIP 处理程序 如果满足以下条件,此处理程序将压缩响应的内容:

  • 过滤器映射到匹配路径
  • 响应状态码 >=200 和
  • 内容长度未知或大于 minGzipSize initParameter 或 minGzipSize 为 0(默认)
  • 内容类型位于 mimeTypes initParameter 中设置的以逗号分隔的 mimeType 列表中,或者如果未定义任何 mimeType,则内容类型不是“application/gzip”
  • 资源未指定内容编码

它应该适用于两者。我只是不确定path 部分,但没有指定任何内容,我希望它适用于两者或都不适用。

我使用window.location.reload(true) 强制重新加载。标题相当长,所以我将它们链接起来:csspng

我尝试设置一些属性,但没有成功。我应该找到 jetty-servlets-9.1.3.v20140225-sources.jar,我去调试一下。问题是:为什么GzipHandler 决定只压缩压缩文件?这是完全确定性的:jpgpng 被压缩(无论多么小),其他文件都没有。

更新

通过setMimeTypes 我可以排除图像。我调试了它,但我仍然不知道为什么其他静态资源永远不会被压缩。我仔细检查了myHandler 是否统一对待它们(它们都直接从预先计算的Map<String, byte[]> 得到服务)。

【问题讨论】:

    标签: http compression jetty embedded-jetty


    【解决方案1】:

    我们可以使用 GzipFilter 来实现这个结果。 GzipFilter 的 Jetty 文档提供了许多详细信息支持的参数列表。要以编程方式启用它,refer this question

    GzipFilter 基本上是一个服务器端过滤器,在处理压缩需求方面非常有效。

    示例过滤器配置

    <filter>
     <filter-name>GZipFilter</filter-name>
     <display-name>Jetty's GZip Filter</display-name>
     <description>Filter that zips all the content on-the-fly</description>
     <filter-class>org.mortbay.servlet.GzipFilter</filter-class>
     <init-param>
      <param-name>mimeTypes</param-name>
      <param-value>text/html</param-value>
     </init-param>
    </filter>
    
    <filter-mapping>
     <filter-name>GZipFilter</filter-name>
     <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    【讨论】:

    • 我想,你是对的,但是使用过滤器看起来比我自己进行压缩的工作要多(缺点是它可能是错误的)。到目前为止,我所做的是通过预先计算的压缩数据来处理静态资源——相当简单。
    • 不要重新发明轮子。不要手动编写压缩逻辑。已经解决了很多次了。添加过滤器可能看起来很复杂,但事实并非如此。如果有帮助,我已经用过滤器配置更新了我的答案
    • 实际上,我重新发明了轮子,它可能比运行过滤器更简单(因为我还没有使用过滤器,也没有使用 XML 等)。我目前仅将它用于预取资源(目前这已经足够了;我将它们全部压缩和未压缩在内存中)。
    • GzipFilter 在 jetty >8 中已弃用,应使用 GzipHandler。现在我正在弄清楚如何..
    • 不仅 GzipFilter 已被弃用,它已被无效的无操作存根取代。见:eclipse.googlesource.com/jetty/org.eclipse.jetty.project/+/…
    【解决方案2】:

    这是我在 Jetty 9.3.7 中配置 GzipHandler 的方式:

    GzipHandler gzipHandler = new GzipHandler();
    gzipHandler.setIncludedMimeTypes("text/html", "text/plain", "text/xml", 
                "text/css", "application/javascript", "text/javascript");
    gzipHandler.setHandler(myHandler);
    handlerList.addHandler(gzipHandler);
    

    在这种情况下,myHandlerResourceHandler 的一个实例。默认情况下,Gzip 处理程序仅 gzip 对响应代码在 200 范围内的 GET 请求的响应。

    【讨论】:

    • 什么是 handlerList 类型?你能发布完整的代码吗?这会放在我的@Configuration 类中吗?
    • handlerList 的类型为 HandlerList。基本上我的代码是这样的:Server s = ...;HandlerList handlerList = new HandlerList();handlerList.add(...);s.setHandlerList(handlerList);handlerList.start();s.start();我不使用@Configuration所以我不能回答这个问题。
    • 谢谢。我在 pom.xml 中使用嵌入式 maven jetty。上面的代码有没有可能集成到我的嵌入式码头?
    【解决方案3】:

    对于接下来的人,这里是如何启用请求解压缩,其中handler 是扩展org.eclipse.jetty.server.handler.AbstractHandler 的类。请求解压的重要部分是includeMethods,默认为GETinflateBuffer,需要>0但默认为0。代码:

        //create server using given threadpool
        Server server = new Server(8080);
    
        GzipHandler gzipHandler = new GzipHandler();
        gzipHandler.setIncludedMethods("PUT", "POST", "GET");
        gzipHandler.setInflateBufferSize(2048);
        gzipHandler.setHandler(handler);
        server.setHandler(gzipHandler);
    
        server.start();
        server.join();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-25
      • 1970-01-01
      • 2021-11-21
      • 2018-11-26
      相关资源
      最近更新 更多