3
我試圖使用Spring MVC控制器來服務某些資產。我的資產是數據庫管理的,因此必須以這種方式提供服務。該服務從數據庫中查找資產的元數據,從文件系統讀取文件並構建響應。無法緩存由Spring MVC提供的圖像
這是我的控制器的樣子。
@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
,我沒有成功。
下面是兩個連續請求期間吐出的HTTP標頭(不相關的標頭刪除)。
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
然而,當我嘗試在網址如
- http://www.google.co.uk/images/srpr/logo4w.png(谷歌的標誌)
- http://fbstatic-a.akamaihd.net/rsrc.php/v2/yI/r/0PsXdTWc41M.png(Facebook的移動相同的序列(按Ctrl + F5的第一個請求和F5爲後續的)圖片)
我看到這些標頭(如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
注:
- 我沒有在我的Spring配置的
<mvc:resources />
節,因爲我做的完全一樣在我的控制器。即使添加它也沒有任何區別。 - 由於上述原因,我沒有在Spring配置中再次定義的
org.springframework.web.servlet.mvc.WebContentInterceptor
。我曾嘗試添加一個沒有收益。 - 我嘗試了所有在https://developers.google.com/speed/docs/best-practices/caching中解釋的方法。
- 我可以在所有瀏覽器中複製此內容。
我應該實現與'asset.getModifiedOn'值進行比較'的If-Modified-Since'請求頭值並返回304的邏輯?這是不是太低級? – adarshr
你必須實現最後修改的檢查,幸運的是,Spring使得這很容易:http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html #mvc-ann-lastmodified –
@Devon_C_Miller是的,這似乎是個伎倆。你可以把它作爲答案發布,以便我可以獎勵你嗎? – adarshr