我正在从我的servlet提供图像。响应内容类型是image / jpeg。我发现从我的servlet请求的图像没有被缓存。如何通过文件图像请求缓存它们?我尝试设置Cache-Control:public但无济于事。
答案 0 :(得分:23)
在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>
答案 1 :(得分:3)
您需要在回复中发送ETag
,Last-Modified
和Expires
标头。 ETag
表示文件的唯一标识符(通常基于filename,filesize和lastmodified timestamp的组合组成)。 Last-Modified
表示文件的上次修改时间戳。 Expires
标头表示允许客户端将文件保留在缓存中的时间。如果缓存已过期并且ETag
或Last-Modified
可用,则客户端将发送HEAD
请求以检查是否需要续订该文件。如果没有,那么Expires
将会相应地再次推迟。
你可以在这里找到一个处理这一切的servlet示例(并下载简历和自动GZIP):FileServlet supporting resume and GZIP
答案 2 :(得分:2)
例如,如果要将它们缓存1个月:
Calendar inOneMonth = Calendar.getInstance();
inOneMonth.add(Calendar.MONTH, 1);
response.setDateHeader("Expires", inOneMonth.getTimeInMillis());
(例如,它位于处理Filter
模式的*.jpg
中)
但是默认情况下应该缓存图像 - 检查过滤器和配置,看看是否有什么东西没有错误地设置缓存参数。
答案 3 :(得分:-8)
好的..看起来默认的头字段应该启用缓存。我在另一个论坛找到了解决方案。显然,您需要在响应中明确设置内容长度。不知道为什么。我认为HttpServletResponse会为我们做到这一点。无论如何,它的工作就像一个魅力,图像很好地缓存。