【发布时间】:2011-02-21 18:58:54
【问题描述】:
我正在从我的 servlet 提供图像。响应内容类型为 image/jpeg。我发现从我的 servlet 请求的图像没有被缓存。我如何让它们像通常的文件图像请求一样被缓存?我尝试设置 Cache-Control: public 但无济于事。
【问题讨论】:
标签: java http image servlets caching
我正在从我的 servlet 提供图像。响应内容类型为 image/jpeg。我发现从我的 servlet 请求的图像没有被缓存。我如何让它们像通常的文件图像请求一样被缓存?我尝试设置 Cache-Control: public 但无济于事。
【问题讨论】:
标签: java http image servlets caching
在 Tomcat 等容器中提供静态内容的默认 servlet 不设置任何缓存控制标头。您不需要为此编写一个 servlet。只需创建一个这样的过滤器,
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
long expiry = new Date().getTime() + cacheAge*1000;
HttpServletResponse httpResponse = (HttpServletResponse)response;
httpResponse.setDateHeader("Expires", expiry);
httpResponse.setHeader("Cache-Control", "max-age="+ cacheAge);
chain.doFilter(request, response);
}
只要你想添加缓存控制,只需将过滤器添加到 web.xml 中的资源。例如,
<filter>
<filter-name>CacheControl</filter-name>
<filter-class>filters.CacheControlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CacheControl</filter-name>
<url-pattern>/images/*</url-pattern>
</filter-mapping>
【讨论】:
cacheAge 是您希望缓存内容的秒数。
您需要在响应中发送ETag、Last-Modified 和Expires 标头。 ETag 表示文件的唯一标识符(通常由文件名、文件大小和 lastmodified 时间戳的组合组成)。 Last-Modified 代表文件的最后修改时间戳。 Expires 标头表示允许客户端将文件保存在缓存中的时间。如果缓存已过期且ETag或Last-Modified可用,则客户端将发送HEAD请求以检查文件是否需要更新。如果没有,那么Expires 将相应地再次推迟。
你可以在这里找到一个处理这一切(并下载简历和自动 GZIP)的 servlet 示例:FileServlet supporting resume and GZIP
【讨论】:
例如,如果您想将它们缓存 1 个月:
Calendar inOneMonth = Calendar.getInstance();
inOneMonth.add(Calendar.MONTH, 1);
response.setDateHeader("Expires", inOneMonth.getTimeInMillis());
(例如,这是在处理*.jpg 模式的Filter 中)
但默认情况下应该缓存图像 - 检查您的过滤器和配置,看看是否有某些东西没有正确设置缓存参数。
【讨论】:
好的.. 看起来默认标头字段应该启用缓存。我在另一个论坛找到了解决方案。显然,您需要在响应中明确设置内容长度。想知道为什么。我认为 HttpServletResponse 会为我们做到这一点。无论如何,它就像一个魅力,图像被很好地缓存了。
【讨论】: