无法缓存Spring MVC提供的图像 [英] Unable to cache images served by Spring MVC

查看:111
本文介绍了无法缓存Spring MVC提供的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Spring MVC控制器来提供一些资产。我的资产是数据库管理的,因此必须以这种方式提供。该服务从数据库中查找资产的元数据,从文件系统中读取文件并构建响应。

I am trying to serve some assets using a Spring MVC controller. My assets are database managed and thus have to be served this way. The service looks up the metadata of the asset from the database, reads the file from file system and builds the response.

以下是我的控制器的样子。

Here is how my controller looks like.

@Controller
@RequestMapping("/assets")
public class AssetController {

    @Autowired
    private AssetService assetService;

    @RequestMapping("/{assetName:.+}")
    public ResponseEntity<byte[]> getAsset(@PathVariable("assetName") String assetName) throws FileNotFoundException, IOException {
        Asset asset = assetService.findByName(assetName);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.valueOf(asset.getContentType()));
        headers.setCacheControl("max-age=1209600");
        headers.setLastModified(asset.getModifiedOn().getTime()); // always in the past

        return new ResponseEntity<byte[]>(assetService.toBytes(asset), headers, OK);
    }
}

看起来简单直接吗?人们希望看到浏览器缓存图像。但是尽管尝试了所有 Cache-Control 的组合, Expires Last-Modified-On ETag ,我没有成功。

Seems simple and straightforward enough? One would hope to see the browser caching the images. But despite trying all combinations of Cache-Control, Expires, Last-Modified-On and ETag, I have had no success.

以下是HTTP标头(不相关标题已删除)在两个连续请求期间吐出。

Below are the HTTP headers (irrelevant headers removed) spit out during two successive requests.

GET /adarshr-web/assets/Acer.png HTTP/1.1
Host: localhost:8080
Pragma: no-cache
Cache-Control: no-cache

HTTP/1.1 200 OK
Cache-Control: max-age=1209600
Last-Modified: Sun, 21 Jul 2013 11:56:32 GMT
Content-Type: image/png
Date: Tue, 23 Jul 2013 21:22:58 GMT
----------------------------------------------------------

GET /adarshr-web/assets/Acer.png HTTP/1.1
Host: localhost:8080
If-Modified-Since: Sun, 21 Jul 2013 11:56:32 GMT
Cache-Control: max-age=0

HTTP/1.1 200 OK <-- Why not 304 Not Modified?
Cache-Control: max-age=1209600
Last-Modified: Sun, 21 Jul 2013 11:56:32 GMT
Content-Type: image/png
Date: Tue, 23 Jul 2013 21:23:03 GMT

然而,当我尝试相同的序列时(Ctrl +网址上的第一次请求F5和后续网址F5)

However, when I try the same sequence (Ctrl + F5 for first request and F5 for subsequent ones) on URLs such as

  • http://www.google.co.uk/images/srpr/logo4w.png (Google's logo)
  • http://fbstatic-a.akamaihd.net/rsrc.php/v2/yI/r/0PsXdTWc41M.png (Facebook's mobile image)

I查看这些标题(显示为Facebook URL),表明浏览器正在缓存响应。

I see the headers such as these (shown for the Facebook URL) which indicate that the response is being cached by the browser.

GET /rsrc.php/v2/yI/r/0PsXdTWc41M.png HTTP/1.1
Host: fbstatic-a.akamaihd.net
Pragma: no-cache
Cache-Control: no-cache

HTTP/1.1 200 OK
Content-Type: image/png
Last-Modified: Sat, 15 Jun 2013 00:48:42 GMT
Cache-Control: public, max-age=31535893
Expires: Wed, 23 Jul 2014 21:27:47 GMT
Date: Tue, 23 Jul 2013 21:29:34 GMT
----------------------------------------------------------

GET /rsrc.php/v2/yI/r/0PsXdTWc41M.png HTTP/1.1
Host: fbstatic-a.akamaihd.net
If-Modified-Since: Sat, 15 Jun 2013 00:48:42 GMT
Cache-Control: max-age=0

HTTP/1.1 304 Not Modified <-- Note this
Content-Type: image/png
Last-Modified: Sat, 15 Jun 2013 00:48:42 GMT
Cache-Control: public, max-age=31535892
Expires: Wed, 23 Jul 2014 21:27:47 GMT
Date: Tue, 23 Jul 2013 21:29:35 GMT

注意:


  • 我没有< mvc:resources /> 我的Spring配置中的部分,因为我在控制器中完全一样。即使添加它也没有任何区别。

  • 我没有 org.springframework.web.servlet.mvc.WebContentInterceptor 由于上述原因,再次在Spring配置中定义。我试过添加一个没有收获的。

  • 我已经尝试了 https://developers.google.com/speed/docs/best-practices/caching

  • 我可以在所有浏览器中复制此内容。

  • I don't have an <mvc:resources /> section in my Spring config since I am doing exactly the same in my controller. Even adding it doesn't make any difference.
  • I don't have a org.springframework.web.servlet.mvc.WebContentInterceptor defined in the Spring config again for the reasons above. I have tried adding one with no gain.
  • I have tried all methods explained in https://developers.google.com/speed/docs/best-practices/caching.
  • I can replicate this across all browsers.

推荐答案

你必须实施上次修改的检查,幸运的是Spring非常简单。

You'll have to implement the check of the last modified, fortunately Spring makes that pretty easy.

来自 Spring Framework Reference

@RequestMapping
public String myHandleMethod(WebRequest webRequest, Model model) {

    long lastModified = // 1. application-specific calculation

    if (request.checkNotModified(lastModified)) {
        // 2. shortcut exit - no further processing necessary
        return null;
     }

    // 3. or otherwise further request processing, actually preparing content
    model.addAttribute(...);
    return "myViewName";
}

这篇关于无法缓存Spring MVC提供的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆