java - Unable to cache images served by Spring MVC -
i trying serve assets using spring mvc controller. assets database managed , have served way. service looks metadata of asset database, reads file file system , builds response.
here how 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()); // in past return new responseentity<byte[]>(assetservice.tobytes(asset), headers, ok); } }
seems simple , straightforward enough? 1 hope see browser caching images. despite trying combinations of cache-control
, expires
, last-modified-on
, etag
, have had no success.
below http headers (irrelevant headers removed) spit out during 2 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 ---------------------------------------------------------- /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
however, when try same sequence (ctrl + f5 first request , f5 subsequent ones) on urls such
- 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 see headers such these (shown facebook url) indicate response being cached 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 ---------------------------------------------------------- /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 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
notes:
- i don't have
<mvc:resources />
section in spring config since doing same in controller. adding doesn't make difference. - i don't have
org.springframework.web.servlet.mvc.webcontentinterceptor
defined in spring config again reasons above. have tried adding 1 no gain. - i have tried methods explained in https://developers.google.com/speed/docs/best-practices/caching.
- i can replicate across browsers.
you'll have implement check of last modified, fortunately spring makes pretty easy.
from 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, preparing content model.addattribute(...); return "myviewname"; }
Comments
Post a Comment