博客
关于我
Spring MVC 中的http Caching
阅读量:421 次
发布时间:2019-03-06

本文共 2777 字,大约阅读时间需要 9 分钟。

文章目录

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
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 1123Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format

如果要在java中使用,参考如下的例子:

@GetMapping("/forecast")ResponseEntity
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
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
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。

@Beanpublic FilterRegistrationBean filterRegistrationBean () {   ShallowEtagHeaderFilter eTagFilter = new ShallowEtagHeaderFilter();   FilterRegistrationBean registration = new FilterRegistrationBean();   registration.setFilter(eTagFilter);   registration.addUrlPatterns("/*");   return registration;}

请注意, ETag计算可能会影响性能。

更多教程请参考

转载地址:http://ggnuz.baihongyu.com/

你可能感兴趣的文章
MySQL - ERROR 1406
查看>>
mysql - 视图
查看>>
MySQL - 解读MySQL事务与锁机制
查看>>
MTTR、MTBF、MTTF的大白话理解
查看>>
mt_rand
查看>>
mysql -存储过程
查看>>
mysql /*! 50100 ... */ 条件编译
查看>>
mudbox卸载/完美解决安装失败/如何彻底卸载清除干净mudbox各种残留注册表和文件的方法...
查看>>
mysql 1264_关于mysql 出现 1264 Out of range value for column 错误的解决办法
查看>>
mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
查看>>
mysql 5.6 修改端口_mysql5.6.24怎么修改端口号
查看>>
MySQL 8.0 恢复孤立文件每表ibd文件
查看>>
MySQL 8.0开始Group by不再排序
查看>>
mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
查看>>
multi swiper bug solution
查看>>
MySQL Binlog 日志监听与 Spring 集成实战
查看>>
MySQL binlog三种模式
查看>>
multi-angle cosine and sines
查看>>
Mysql Can't connect to MySQL server
查看>>
mysql case when 乱码_Mysql CASE WHEN 用法
查看>>