java - 无法缓存由 Spring MVC 提供的图像

标签 java http caching spring-mvc

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

这是我的 Controller 的样子。

@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-OnETag ,我没有成功。

以下是在两次连续请求期间吐出的 HTTP header (不相关的 header 已删除)。

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

但是,当我在诸如

我看到诸如此类的 header (针对 Facebook URL 显示)表明浏览器正在缓存响应。

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 配置中的部分,因为我在我的 Controller 中做的完全相同。即使添加它也没有任何区别。
  • 我没有 org.springframework.web.servlet.mvc.WebContentInterceptor由于上述原因,再次在 Spring 配置中定义。我尝试添加一个但没有任何收获。
  • 我已经尝试了 https://developers.google.com/speed/docs/best-practices/caching 中说明的所有方法.
  • 我可以在所有浏览器上复制它。

最佳答案

您必须执行最后修改的检查,幸运的是 Spring 使这变得非常简单。

来自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";
}

关于java - 无法缓存由 Spring MVC 提供的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17821518/

相关文章:

php - 出于性能原因,我应该使用 SQL 限制吗?

java - 这个 java for 循环条件有什么问题?

java - ORMLite id 始终为 null(没有 id 字段)

json - 如何从 Dart http 调用中返回 json/如何完全使用流?

javascript - 我如何使用可请求扩展的 Bluebird promise ?

php - 频繁使用网站的缓存策略

java - readShort()期间如果出现超时异常,socket接收到的数据会发生什么情况?

java - Apache Mahout中的WrongValueClass

sockets - 为什么代码显示 "Error 354 (net::ERR_CONTENT_LENGTH_MISMATCH): The server unexpectedly closed the connection."

c++ - 在Intel x86中读取缓存行与部分缓存行