Spring MVC 中的http Caching
Spring MVC 中的http Caching
Cache 是HTTP协议中的一个非常重要的功能,使用Cache可以大大提高应用程序的性能,减少数据的网络传输。
通常来说我们会对静态资源比如:图片,CSS,JS文件等做缓存。同样的我们可以使用HTTP Cache配合Spring MVC来做动态资源的缓存。
那么什么时候使用动态资源的缓存呢?
只有当这个资源不经常更新或者你确切的知道该资源什么时候更新的时候就可以使用HTTP Cache了。
HTTP Cache是通过请求头来实现的,主要有三种方式:过期时间,最后更新时间和Etag。
其中过期时间是客户端验证,最后更新时间和Etag是服务器端验证。
过期时间
过期时间又有两种方式,分别是Cache-Control和Expires头。
在Cache-Control中,我们可以设置它的maxAge,超出该时间后,该资源才会被再次请求。如下所示:
@GetMapping("/{id}")
ResponseEntity<Product> getProduct(@PathVariable long id) {
// …
CacheControl cacheControl = CacheControl.maxAge(30, TimeUnit.MINUTES);
return ResponseEntity.ok()
.cacheControl(cacheControl)
.body(product);
}
我们也可以在Head中设置Expires属性。Expires的时间需要是标准时间格式,如下:
Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
如果要在java中使用,参考如下的例子:
@GetMapping("/forecast")
ResponseEntity<Forecast> getTodaysForecast() {
// ...
ZonedDateTime expiresDate = ZonedDateTime.now().with(LocalTime.MAX);
String expires = expiresDate.format(DateTimeFormatter.RFC_1123_DATE_TIME);
return ResponseEntity.ok()
.header(HttpHeaders.EXPIRES, expires)
.body(weatherForecast);
}
如果Cache-Control和Expires同时出现,则会优先使用 Cache-Control。
Last-Modified
它的验证逻辑是这样的,客户端会根据上次请求得到的Last-Modified设置它的If-Modified-Since,服务器端接收到了这个属性之后可以跟之前的进行比较,如果相同则可以返回一个空的body。如下所示:
@GetMapping("/{id}")
ResponseEntity<Product> getProduct(@PathVariable long id, WebRequest request) {
Product product = repository.find(id);
long modificationDate = product.getModificationDate()
.toInstant().toEpochMilli();
if (request.checkNotModified(modificationDate)) {
return null;
}
return ResponseEntity.ok()
.lastModified(modificationDate)
.body(product);
}
ETag
Last-Modified的时间只能精确到秒,如果还需要更细粒度的话,就需要用到ETag了。
ETag可以看成当前时刻某个资源的唯一标记,你可以取该资源的hash值作为ETag。
下面是它的一种实现:
@GetMapping("/{id}")
ResponseEntity<Product> getProduct(@PathVariable long id, WebRequest request) {
Product product = repository.find(id);
String modificationDate = product.getModificationDate().toString();
String eTag = DigestUtils.md5DigestAsHex(modificationDate.getBytes());
if (request.checkNotModified(eTag)) {
return null;
}
return ResponseEntity.ok()
.eTag(eTag)
.body(product);
}
Spring ETag filter
Spring提供了一个ShallowEtagHeaderFilter来根据返回的内容自动为你生成Etag。
@Bean
public FilterRegistrationBean filterRegistrationBean () {
ShallowEtagHeaderFilter eTagFilter = new ShallowEtagHeaderFilter();
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(eTagFilter);
registration.addUrlPatterns("/*");
return registration;
}
请注意, ETag计算可能会影响性能。
更多教程请参考 flydean的博客
Spring MVC 中的http Caching的更多相关文章
- Spring mvc中@RequestMapping 6个基本用法
Spring mvc中@RequestMapping 6个基本用法 spring mvc中的@RequestMapping的用法. 1)最基本的,方法级别上应用,例如: Java代码 @Reques ...
- spring mvc中使用freemark的一点心得
参考文档: FreeMarker标签与使用 连接http://blog.csdn.net/nengyu/article/details/6829244 freemarker学习笔记--指令参考: ht ...
- Http请求中Content-Type讲解以及在Spring MVC中的应用
引言: 在Http请求中,我们每天都在使用Content-type来指定不同格式的请求信息,但是却很少有人去全面了解content-type中允许的值有多少,这里将讲解Content-Type的可用值 ...
- Spring mvc中@RequestMapping 6个基本用法小结(转载)
小结下spring mvc中的@RequestMapping的用法. 1)最基本的,方法级别上应用,例如: @RequestMapping(value="/departments" ...
- Spring MVC中处理静态资源的多种方法
处理静态资源,我想这可能是框架搭建完成之后Web开发的”头等大事“了. 因为一个网站的显示肯定会依赖各种资源:脚本.图片等,那么问题来了,如何在页面中请求这些静态资源呢? 还记得Spring MVC中 ...
- Spring MVC 中的基于注解的 Controller【转】
原文地址:http://my.oschina.net/abian/blog/128028 终于来到了基于注解的 Spring MVC 了.之前我们所讲到的 handler,需要根据 url 并通过 H ...
- spring mvc中的文件上传
使用commons-fileupload上传文件所需要的架包有:commons-fileupload 和common-io两个架包支持,可以到Apache官网下砸. 在配置文件spring-mvc.x ...
- spring mvc中的valid
当你希望在spring mvc中直接校验表单参数时,你可以采用如下操作: 声明Validator的方式: 1.为每一个Controller声明一个Validator @Controller publi ...
- spring mvc中的@PathVariable(转)
鸣谢:http://jackyrong.iteye.com/blog/2059307 ------------------------------------------------ spring m ...
随机推荐
- 当阿里面试官问我:Java创建线程有几种方式?我就知道问题没那么简单
这是最新的大厂面试系列,还原真实场景,提炼出知识点分享给大家. 点赞再看,养成习惯~ 微信搜索[武哥聊编程],关注这个 Java 菜鸟. 昨天有个小伙伴去阿里面试实习生岗位,面试官问他了一个老生常谈的 ...
- 大曾Blogs使用说明书😊——Super ITZ
大曾Blogs使用说明书 先敲黑板,四句话: pipe搜索,简洁,用于跳转,博客园及csdn和github 博客园炫酷界面,用于查看主要博文 csdn所有博客汇总,查看详细信息 github项目源码汇 ...
- Python库-NumPy
NumPy是一个开源的Python科学计算库,用于快速处理任意维度的数组. 创建NumPy数组 #创建一维数组 list1 = [1,2,3,4] array1= np.array(list1)#用p ...
- vue实现首屏加载等待动画 避免首次加载白屏尴尬
0 直接上效果图 1背景,用户体验良好一直是个重要的问题. 2怎么加到自己项目里面? 复制css html代码到自己的index.html即可 代码链接 源码地址 Vue学习前端群493671066, ...
- Python操作rabbitmq系列(二):多个接收端消费消息
今天,我们要逐步开始讨论rabbitmq稍微高级点的耍法了.了解这一步,对我们设计高并发的系统非常有用.当然,还可以使用kafka.不过还是算了,有几个硬性条件不支持,还是用rabbitmq吧. 循环 ...
- [安卓] 21、android studio 疑难杂症
目录 1 gradle问题 1.1 gradle版本不匹配导致的错误: . 1 gradle问题 1.1 gradle版本不匹配导致的错误: 背景:在导入telink ble ota安卓源码时遇到an ...
- python 字节码死磕
前言: 如果你跟我一样,对python的字节码感兴趣,想了解python的代码在内存中到底是怎么去运行的,那么你可以继续往下看,如果你是python新手,我建议你移步它处,本文适合有点基础的pyth ...
- Linux下搭建接口自动化测试平台
前言 我们今天来学习一下在Linux下如何搭建基于HttpRunner开发的接口自动化测试平台吧! 需要在Linux上提前准备的环境(下面是本人搭建时的环境): 1,Python 3.6.8 (可参考 ...
- 09-sass
一.sass和scss sass最初是为了配合haml设计的,不需要大括号,用tab缩进 从第三代开始,保留缩进风格,完全向下兼容普通的css代码 二.下载配置sass compass是sass的一个 ...
- 01-css3之过渡
一.介绍 过渡(transition)是CSS3中具有颠覆性的特征之一,我们可以在不使用 Flash 动画或 JavaScript 的情况下,当元素从一种样式变换为另一种样式时为元素添加效果,经常和 ...