简体   繁体   English

缓存servlet提供的图像

[英]caching images served by servlet

I'm serving up images from my servlet. 我正在从我的servlet提供图像。 The response content type is image/jpeg. 响应内容类型是image / jpeg。 I find that images requested from my servlet are not cached. 我发现从我的servlet请求的图像没有被缓存。 How do I get them to be cached like file image requests normally are? 如何通过文件图像请求缓存它们? I tried setting Cache-Control: public but to no avail. 我尝试设置Cache-Control:public但无济于事。

The default servlet serving static content in containers like Tomcat doesn't set any cache control headers. 在Tomcat等容器中提供静态内容的默认servlet不会设置任何缓存控制头。 You don't need write a servlet just for that. 您不需要为此编写servlet。 Just create a filter like this, 只需创建一个这样的过滤器,

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);

 }

Whenever you want add cache control, just add the filter to the resources in web.xml. 无论何时需要添加缓存控制,只需将过滤器添加到web.xml中的资源即可。 For example, 例如,

<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>

You need to send the ETag , Last-Modified and Expires headers along the response. 您需要在响应中发送ETagLast-ModifiedExpires标头。 The ETag represents the unique identifier of the file (usually composed based on a combination of filename, filesize and lastmodified timestamp). ETag表示文件的唯一标识符(通常基于文件名,文件大小和最后修改的时间戳的组合组成)。 The Last-Modified represents the last modified timestamp of the file. Last-Modified表示文件的上次修改时间戳。 The Expires header denotes how long the client is allowed to keep the file in cache. Expires标头表示允许客户端将文件保留在缓存中的时间。 If the cache has been expired and the ETag or Last-Modified are available, then the client will send a HEAD request to check if the file needs to be renewed. 如果缓存已过期并且ETagLast-Modified可用,则客户端将发送HEAD请求以检查是否需要续订该文件。 If not, then the Expires will just be postponed again accordingly. 如果没有,则Expires将再次相应推迟。

You can find here a servlet example which handles this all (and download resumes and automatic GZIP): FileServlet supporting resume and GZIP 你可以在这里找到一个处理这一切的servlet示例(并下载简历和自动GZIP): FileServlet支持简历和GZIP

For example, if you want to cache them for 1 month: 例如,如果要将它们缓存1个月:

Calendar inOneMonth = Calendar.getInstance();
inOneMonth.add(Calendar.MONTH, 1);

response.setDateHeader("Expires", inOneMonth.getTimeInMillis());

(this is in a Filter that handles the *.jpg pattern, for example) (例如,在处理*.jpg模式的Filter中)

But images should be cached by default - check your filters and configurations to see if something isn't setting the cache parameters incorrectly. 但是默认情况下应该缓存图像 - 检查过滤器和配置以查看是否有些内容未正确设置缓存参数。

Ok.. looks like the default header fields should enable caching. 好..看起来默认的头字段应该启用缓存。 I found a solution in another forum. 我在另一个论坛找到了解决方案。 Apparently, you need to explicitly set a content-length in the response. 显然,您需要在响应中明确设置内容长度。 Wonder why though. 不知道为什么。 I thought the HttpServletResponse would do that for us. 我认为HttpServletResponse会为我们做到这一点。 Anyway, it worked like a charm and the image is getting cached nicely. 无论如何,它就像一个魅力,图像得到很好的缓存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM