#练习下Spring MVC对HTTP Cache的支持
##注意 只要是请求,就能cache,无论是html、json、xml、jsp还是什么的,只要是请求,就能缓存。
##eTag(entity Tag)
The ETag HTTP response header is an identifier for a specific version of a resource.
是服务器响应时,添加的一个响应头,其值是服务器端给出的。
浏览器拿到这个eTag之后,会按照URL将内容存储起来,供后续请求使用。
如果后续请求继续访问这个URL,那会携带上eTag -- If-None-Match:${eTag}。
服务器端会判断这个eTag是否发生了更改,如果没有更改,那直接返回304,不需要返回更多内容。
注意:这个判断,其实还是通过代码判断的,Spring MVC应该是配置了拦截器或者过滤器,所以用起来更简单。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag
##last-modified
这也是一个header,是早期的缓存header吧。
用的好像是时间戳,但只能精确到秒级别,见CatController#getLastModified()。
the Last-Modified header will contain the date of last modification.
Unlike If-Unmodified-Since, If-Modified-Since can only be used with a GET or HEAD.
The most common use case is to update a cached entity that has no associated ETag.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since
##Spring提供的HTTP cache支持,Controller级别有三种方式:
(1) 对静态资源(js、css、icons等),添加ResourceHandlers即可。见MvcConfig#addResourceHandlers()。
(2) Controller中,使用ResponseEntity直接处理 - 设置缓存、eTag,后续Spring会自动处理。需要指定eTag的值。见BookController#showBook()。
(3) 手动处理,Controller的参数中注入WebRequest对象,然后WebRequest#checkLastModified()。如果true,直接返回null即可,Spring会帮忙处理。
###WebRequest#checkLastModified() 有三种变体,分别是:
request.checkNotModified(lastModified) 会比较lastModified 和 If-Modified-Since 或 If-Unmodified-Since request header。
request.checkNotModified(eTag) 会比较 eTag 和 If-None-Match request header。
request.checkNotModified(eTag, lastModified) 二者都比较,意味着两种条件应该都有效。
当接收 conditional GET/HEAD requests时, checkNotModified 会检查resource是否没有被修改;如果没有,它会返回一个HTTP 304 Not Modified response。
而在POST/PUT/DELETE requests时,checkNotModified 会检查resouce是否没有被修改;如果有修改,会返回一个HTTP 409 Precondition Failed response 来阻止并发修改。
##Spring提供的HTTP cache支持,Servlet级别:
对于ETags的支持是由Servlet filter ShallowEtagHeaderFilter提供的。
这是一个简单的Servlet Filter,因此可与任何web框架结合使用。
ShallowEtagHeaderFilter filter 会创建 shallow ETags (与deep ETags相对,后面有讲)。
该filter会缓存被渲染的JSP的内容(或其他内容),生成一个MD5 hash,并将其返回作为response的一个ETag header。
等下次客户端请求同样的资源时,它会使用该hash作为 If-None-Match value。
该filter会侦测到它,重新渲染视图,然后比较二者的hash。
如果相等,返回304。
注意,这种策略节省了网络带宽,而非CPU,因为仍然需要为每次request计算response。建议不要使用,除非你懒得写Controller中的判断逻辑。
而controller级别的其他策略(前面的),则既能节省带宽,又能避免计算。
##Firefox cache
关键点,Firefox 并不是将这个内容保存到cookie或其他,而是保存到本地磁盘上!!!
使用 about:cache查看,点开disk项的List Cache Entries,并页面搜索URL,点开即可看到相应的内容。
##cache vs cookie
什么关系???
cookie是和session对应的,会话级别。保存会话id之类的东西。
cache是缓存,可以算请求级别吧。因为,ajax请求json时,肯定也会有cache,而非cookie。
最关键的,cache都可以访问,cookie不能跨域。
##参考 http://blog.csdn.net/lonelyrains/article/details/7838074
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。