【问题标题】:Servlet filter for browser caching?用于浏览器缓存的 Servlet 过滤器?
【发布时间】:2011-03-23 10:16:33
【问题描述】:

有谁知道如何编写一个 servlet 过滤器,该过滤器将在给定文件/内容类型的响应中设置缓存标头?我有一个提供大量图像的应用程序,我想通过让浏览器缓存不经常更改的图像来减少托管它的带宽。理想情况下,我希望能够指定内容类型并在内容类型匹配时设置适当的标题。

有人知道怎么做吗?或者,更好的是,有他们愿意分享的示例代码?谢谢!

【问题讨论】:

    标签: java servlets caching servlet-filters


    【解决方案1】:

    在你的过滤器中有这一行:

    chain.doFilter(httpRequest, new AddExpiresHeaderResponse(httpResponse));
    

    响应包装器的样子:

    class AddExpiresHeaderResponse extends HttpServletResponseWrapper {
    
        public static final String[] CACHEABLE_CONTENT_TYPES = new String[] {
            "text/css", "text/javascript", "image/png", "image/jpeg",
            "image/gif", "image/jpg" };
    
        static {
            Arrays.sort(CACHEABLE_CONTENT_TYPES);
        }
    
        public AddExpiresHeaderResponse(HttpServletResponse response) {
            super(response);
        }
    
        @Override
        public void setContentType(String contentType) {
            if (contentType != null && Arrays.binarySearch(CACHEABLE_CONTENT_TYPES, contentType) > -1) {
                Calendar inTwoMonths = GeneralUtils.createCalendar();
                inTwoMonths.add(Calendar.MONTH, 2);
    
                super.setDateHeader("Expires", inTwoMonths.getTimeInMillis());
            } else {
                super.setHeader("Expires", "-1");
                super.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
            }
            super.setContentType(contentType);
        }
    }
    

    简而言之,这会创建一个响应包装器,它会在设置内容类型时添加 expires 标头。 (如果你愿意,你也可以添加你需要的任何其他标题)。我一直在使用这个过滤器 + 包装器,它可以工作。

    See this question 这个解决的一个具体问题,以及 BalusC 的原始解决方案。

    【讨论】:

    • 或者,如果您将所有这些文件放在一个公共文件夹中,例如/static,然后只需将过滤器映射到 /static/*url-pattern 上,这样您就不需要每次都检查内容类型,直接设置响应头即可。
    • 这不适用于 GlassFish 上的 SSL/TLS 资源,因为容器会自动添加 Pragma 和 Cache-Control 标头。如果要缓存这些资源,则需要使用以下内容删除/覆盖这些标头: super.setHeader("Pragma", null);和 super.setHeader("Cache-Control", null)。 Cache-Control: "public" 也可能会起作用。注意:使用 null 可能不可移植,因为它不在规范中。可能有一种方法可以禁止容器添加标头,但没有很好的文档记录。
    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-24
      • 1970-01-01
      • 2015-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多