HTTP缓存与Spring示例

缓存是HTTP协议的强大功能,但由于某些原因,它主要用于静态资源,例如图像,CSS样式表或JavaScript文件。 但是,HTTP缓存不仅限于应用程序的资产,您还可以将其用于动态计算的资源。

只需少量工作,您就可以加速应用程序并改善整体用户体验。 在本文中,您将学习如何对Spring控制器的结果使用内置的HTTP响应缓存机制

1.如何以及何时使用HTTP响应缓存?

您可以在应用程序的多层上进行缓存。 数据库具有其缓存存储, 应用程序将一些数据缓存在操作内存中 ,Web客户端也在其侧重用信息。

您可能知道,HTTP协议负责网络通信。 缓存机制使我们可以通过减少客户端与服务器之间传输的数据量来优化网络流量。

您可以(并且应该)优化什么?

当网络资源不经常更改或您确切知道其更新时间时 ,您便是使用HTTP缓存进行优化的理想人选。

一旦确定了用于HTTP缓存的竞争者,就需要选择一种合适的方法来管理缓存的验证。 HTTP协议定义了几个请求和响应头,可用于控制客户端何时应清除缓存

适当的HTTP标头的选择取决于您要优化的特定情况。 但是,无论用例如何,我们都可以根据缓存的验证位置划分缓存管理选项。 它可以由客户端或服务器验证。

让我们继续上演这个节目。

HTTP缓存

2.客户端缓存验证

当您知道请求的资源在给定时间内不会更改时,服务器可以将此类信息作为响应头发送给客户端。 根据该信息,客户端决定是应该重新获取资源还是重用先前下载的资源。

有两个可能的选项来描述客户端何时应再次获取资源并删除存储的缓存值。 因此,让我们看看它们的实际效果。

HTTP缓存在固定时间内有效

如果要防止客户端在给定的时间内重新获取资源 ,则应查看Cache-Control标头,您可以在其中指定应将提取的数据重用多长时间。

通过将标头的值设置为max-age = <seconds>,您可以通知客户端不必再提取资源多长时间。 缓存值的有效性与请求时间有关。

为了在Spring的控制器中设置HTTP标头,而不是常规的有效负载对象,您应该返回ResponseEntity包装器类 。 这是一个例子:

@GetMapping("/{id}")
ResponseEntity<Product> getProduct(@PathVariable long id) {// …CacheControl cacheControl = CacheControl.maxAge(30, TimeUnit.MINUTES);return ResponseEntity.ok().cacheControl(cacheControl).body(product);
}

标头的值只是一个常规的String,但在Cache-Control的情况下,Spring为我们提供了一个特殊的构建器类,该类可防止我们犯小错误,例如拼写错误。

HTTP缓存有效至固定日期

有时您知道什么时候资源会改变。 这是经常发布的数据的常见情况,例如天气预报或为昨天的交易时段计算的股市指标。 资源的确切到期日期可以向客户端公开。

为此,您应该使用Expires HTTP标头。 日期值应使用一种标准化的数据格式进行格式化 。

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);
}

注意, HTTP日期格式需要有关时区的信息 。 这就是为什么上面的示例使用ZonedDateTime的原因 。 如果尝试使用LocalDateTime ,则在运行时将出现以下错误消息:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds

如果响应中同时存在Cache-ControlExpires标头,则客户端仅使用Cache-Control

3.服务器端缓存验证

在基于用户输入动态生成的内容中,服务器不知道何时更改请求的资源的情况更为常见。 在这种情况下,客户端可以使用以前获取的数据,但首先,它需要询问服务器该数据是否仍然有效。

自日期以来是否修改过资源?

如果您跟踪Web资源的修改日期,则可以将该日期作为响应的一部分向客户端公开。 在下一个请求中,客户端会将这个日期发送回服务器,以便它可以验证自上一个请求以来是否已修改资源。 如果资源没有更改,则服务器不必再次重新发送数据。 相反,它使用304 HTTP代码进行响应,而没有任何有效负载。

HTTP缓存

要公开资源的修改日期,您应该设置Last-Modified标头。 Spring的ResponseEntity构建器具有一个名为lastModified()的特殊方法 ,该方法可以帮助您以正确的格式分配值。 您将在一分钟内看到它。

但是在发送完整响应之前,您应该检查客户端是否在请求中包括 If-Modified-Since 标头 。 客户端根据与该特定资源的先前响应一起发送的Last-Modified标头的值来设置其值。

如果If-Modified-Since标头的值与请求的资源的修改日期匹配,则可以节省一些带宽并以空主体响应客户端。

再次,Spring提供了一个辅助方法,该方法简化了上述日期的比较。 可以在WebRequest包装器类中找到称为checkNotModified()的方法,您可以将其添加到控制器的方法中作为输入。

听起来复杂吗?

让我们仔细看一下完整的示例。

@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);
}

首先,我们获取请求的资源并访问其修改日期。 我们将日期转换为格林尼治标准时间1970年1月1日以来的毫秒数,因为那是Spring框架所期望的格式。

然后,我们将日期与If-Modified-Since标头的值进行比较,并在正匹配项上返回一个空主体。 否则,服务器会发送完整的响应正文,并带有Last-Modified头的适当值。

有了这些知识,您几乎可以涵盖所有常见的缓存候选对象。 但是,您应该知道还有一个更重要的机制是……

使用ETag进行资源版本控制

到目前为止,我们将有效期的精度定义为一秒的精度。

但是,如果您需要比一秒钟更高的精度呢?

这就是ETag进入的地方。

可以将ETag定义为唯一的字符串值,该字符串值可以在时间点上明确标识资源。 通常,服务器根据给定资源的属性或(如果可用)其最新修改日期来计算ETag。

客户端和服务器之间的通信流程几乎与修改日期检查的情况相同。 仅标题的名称和值不同。

服务器设置在所谓的(令人惊奇地) 的ETag报头中的ETag值。 当客户端再次访问资源时,它应该在名为If-None-Match的标头中发送其值。 如果该值与资源的新计算的ETag匹配,则服务器可以使用空主体和HTTP代码304进行响应。

在Spring中,您可以实现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);
}

看起来相似吗?

是的,样本与修改日期检查的前一个样本几乎相同。 我们只是使用一个不同的值进行比较(并使用MD5算法来计算ETag)。 注意, WebRequest 有一个重载的 checkNotModified() 方法来处理表示为字符串的ETag。

如果Last-ModifiedETag的工作原理几乎相同,为什么我们需要两者?

HTTP缓存

最后修改与ETag

正如我已经提到的, Last-Modified标头的精度较低,因为它的精度为一秒钟。 为了获得更高的精度,请选择ETag

当您不跟踪资源的修改日期时,还必须使用ETag 。 服务器可以基于资源的属性来计算其值。 可以将其视为对象的哈希码。

如果资源具有其修改日期,并且一秒钟的精度适合您,请使用Last-Modified标头。 为什么? 因为ETag计算可能是一项昂贵的操作

顺便说一句,值得一提的是HTTP协议没有指定用于计算ETag的算法。 选择算法时,您应该专注于其速度。

本文重点介绍缓存GET请求,但您应该知道服务器可以使用ETag同步更新操作。 但这是另一篇文章的想法。

Spring ETag过滤器

由于ETag只是内容的字符串表示形式,因此服务器可以使用响应的字节表示形式来计算其值。 这意味着您实际上可以将ETag分配给任何响应。

你猜怎么着?

Spring框架为您提供了ETag响应过滤器实现 ,该实现为您完成。 您要做的就是在应用程序中配置过滤器。

在Spring应用程序中添加HTTP过滤器的最简单方法是通过配置类中的FilterRegistrationBean

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

在这种情况下,对addUrlPatterns()的调用是多余的,因为默认情况下所有路径都匹配。 我将其放在此处以演示您可以控制Spring应该向其添加ETag值的资源。

除了生成ETag之外,过滤器还尽可能以HTTP 304和空主体作为响应。

但是要当心。

ETag计算可能很昂贵。 对于某些应用程序,启用此过滤器实际上可能造成弊大于利 。 使用它之前,请先考虑一下您的解决方案。

结论

这篇文章看起来很长,但是我们涵盖了很多有用的材料。 现在,您知道如何使用HTTP缓存优化应用程序,以及哪种方法最适合您,因为应用程序具有不同的需求。

您了解到客户端缓存验证是最有效的方法,因为不涉及数据传输。 如果适用,您应该始终支持客户端缓存验证。

我们还讨论了服务器端验证,并比较了Last-ModifiedETag标头。 最后,您了解了如何在Spring应用程序中设置全局ETag过滤器。

希望本文对您有所帮助。 如果您喜欢,请在下面分享或写下您的评论。 另外,请告诉我是否可以改善或扩展内容。 我很想知道你的想法。

翻译自: https://www.javacodegeeks.com/2018/10/http-cache-spring-examples.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/345742.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国家开放大学2021春1378管理英语3题目

试卷代号&#xff1a; 1378 2021年春季学期期末统一考试 管理英语3 试题 2021年7月 注意事项 一、将你的学号、姓名及分校&#xff08;工作站&#xff09;名称填写在答题纸的规定栏内。考试结束后&#xff0c;把试卷和答题纸放在桌上。试卷和答题纸均不得带出考场。监考人收完考…

三层网络结构理解

1. 三层网络结构&#xff08;核心层 汇聚层 接入层&#xff09; 三层网络结构是采用层次化架构的三层网络。三层网络架构采用层次化模型设计&#xff0c;即将复杂的网络设计分成几个层次&#xff0c;每个层次着重于某些特定的功能&#xff0c;这样就能够使一个复杂的大问题变成…

国家开放大学2021春1474临床医学概论(本)题目

试卷代号&#xff1a;1474 2021年春季学期期末统一考试 临床医学概论《本》 试题 2021年7月 一、单项选择题&#xff08;每题2分&#xff0c;共50分&#xff09; 1.口腔温度38.1℃&#xff5e;39℃&#xff0c;属于&#xff08; &#xff09;。 A.正常 B.低热 C.中热 D.高热 E.…

【渝粤题库】国家开放大学2021春1253C语言程序设计题目

试卷代号&#xff1a; 1253 2021年春季学期期末统一考试 C语言程序设计 试题 2021年7月 一、单项选择题&#xff08;把合适的选项编号填写在括号内。每小题3分&#xff0c;共42分&#xff09; 1.C语言中使用的字符常量&#xff0c;其起止标记符是( )。 A.单引号 B.双引号 C.中括…

【渝粤题库】国家开放大学2021春1254计算机组成原理题目

试卷代号&#xff1a;1254 2021年春季学期期末统一考试 计算机组成原理 试题 2021年7月 一、选择题&#xff08;每小题3分&#xff0c;共36分&#xff09; 1.下列数中最大的数是( )。 A. (101001)2 B. (52) s C.(O0111O01)BCD D.(2C)16 2.两个补码数相减&#xff0c;在符号位相…

【渝粤题库】国家开放大学2021春1258房屋建筑混凝土结构设计题目

试卷代号&#xff1a; 1258 2021年春季学期期末统一考试 房屋建筑混凝土结构设计 试题 2021年7月 一、单项选择题&#xff08;每小题2分&#xff0c;共计40分&#xff09; 1.( )主要承担楼&#xff08;屋&#xff09;面上的使用荷载&#xff0c;并将荷载传至竖向承重结构&#…

卫星系统采用的轨道类型

倾斜圆轨道星座 用于卫星网络的星座设计 1. Walker star(极轨道星座)卫星网络 2. Walker delta(倾斜星座)卫星网络 3. Ballard的玫瑰&#xff08;Rosette&#xff09;星座 等效于Walker的Delta星座 http://www.jos.org.cn/html/2014/5/4581.htm#outline_anchor_17

gc 吞吐量和停顿时间_GC对吞吐量和延迟的影响

gc 吞吐量和停顿时间每个Java应用程序都必须解决的一种类型的问题与垃圾回收有关。 当垃圾收集器工作时&#xff0c;它代表了一项奇妙的发明。 如果不是这样&#xff0c;或者GC做家务的方式变得不可预测&#xff0c;那么您就有一个朋友变成了敌人。 这篇文章是关于垃圾收集暂停…

【渝粤题库】国家开放大学2021春1283社会保障学(本)题目

试卷代号&#xff1a; 1283 2021年春季学期期末统一考试 社会保障学&#xff08;本&#xff09; 试题 2021年7月 一、单项选择题&#xff08;在各题的备选答案中&#xff0c;只有1项是正确的&#xff0c;请将正确答案的序号填写在括号内。每小题2分&#xff0c;共26分&#xff…

【渝粤题库】国家开放大学2021春1292企业集团财务管理题目

试卷代号&#xff1a; 1292 2021年春季学期期末统一考试 企业集团财务管理 试题&#xff08;开卷&#xff09; 2021年7月 一、单项选择题&#xff08;将正确答案的字母序号填入括号内。每小题2分&#xff0c;共20分&#xff09; 1.当投资企业拥有被投资企业有表决权的资本比例超…

浅谈排队论

排队论起源于 1909 年丹麦电话工程师 A. K&#xff0e;爱尔朗的工作&#xff0c;他对电话通话拥挤问 题进行了研究。1917 年&#xff0c;爱尔朗发表了他的著名的文章—“自动电话交换中的概率理 论的几个问题的解决”。排队论已广泛应用于解决军事、运输、维修、生产、服务、库…

Java 8 Stream API示例

您好朋友&#xff0c;在本文中&#xff0c;我们将讨论Java 8 Stream API示例。 因此&#xff0c;我们要做的是&#xff0c;创建一个Player类&#xff0c;创建Player类的多个对象&#xff0c;然后创建一个测试类&#xff0c;在其中使用Stream API检索播放器的数据。 第一个例子…

【渝粤题库】国家开放大学2021春1304管理案例分析题目

试卷代号&#xff1a;1304 2021年春季学期期末统一考试 管理案例分析 试题 2021年7月 注意事项 一、将你的学号、姓名及分校&#xff08;工作站&#xff09;名称填写在答题纸的规定栏内。考试结束后&#xff0c;把试卷和答题纸放在桌上。试卷和答题纸均不得带出考场。监考人收完…

【渝粤题库】国家开放大学2021春1313学前儿童卫生与保健题目

试卷代号&#xff1a;1313 2021年春季学期期末统一考试 学前儿童卫生与保健 试题 2021年7月 一、单项选择题&#xff08;在各题的备选答案中&#xff0c;只有一项是正确的&#xff0c;请将正确答案的序号&#xff0c;填写在括号内。每小题3分&#xff0c;共36分&#xff09; 1.…

概率密度函数、概率分布函数、常见概率分布

1. 概率函数 概率函数&#xff0c;就是用函数的形式来表达概率。 piP(Xai)(i1,2,3,4,5,6)p_iP(Xa_i)(i1,2,3,4,5,6)pi​P(Xai​)(i1,2,3,4,5,6) 在这个函数里&#xff0c;自变量&#xff08;X&#xff09;是随机变量的取值&#xff0c;因变量&#xff08;pip_ipi​&#xff09…

【渝粤题库】国家开放大学2021春1332中文学科论文写作题目

试卷代号&#xff1a;1332 2021年春季学期期末统一考试 中文学科论文写作 试题&#xff08;开卷&#xff09; 2021年7月 一、填空&#xff08;每空1分&#xff0c;共10分&#xff09; 1&#xff0e;人们在写作中常用的表达方式有叙述、描写、、 等几种&#xff0c;这几种表达方…

Moment Generating Function

1. 概率统计中的“矩”是什么&#xff1f; 对比物理的力矩&#xff0c;你会发现&#xff0c;概率论中的“矩”真的是很有启发性的一个词。 1.1 力矩 大家应该都知道物理中的力矩&#xff0c;我这里也不展开说细节了&#xff0c;用一幅图来帮助大家回忆一下&#xff1a; 1.…

Lyapunov and Stability Theory

一、什么是稳定点 一个控制系统就和一个社会一样&#xff0c;稳定性是首先要解决的重要问题&#xff0c;是其他一切工作的基础。稳定性问题的字面意思很好理解了&#xff0c;那就是系统在受到扰动后&#xff0c;能否能有能力在平衡态继续工作。大家都知道&#xff0c;历史上社…

迁移学习 简而言之_简而言之Java.io:22个案例研究

迁移学习 简而言之这篇文章试图涵盖java.io中的一整套操作。 与与此主题相关的其他书籍和博客相比&#xff0c;我的动机是通过案例研究来展示“操作方法”。 曾经是Java的学生&#xff0c;我意识到学习一种新的程序语言的最有效方法是通过示例&#xff1a;复制并粘贴一段代码&a…

对采样的理解

1. 什么是采样 我们知道了一个变量的分布&#xff0c;要生成一批服从这个分布的样本&#xff0c;这个过程就叫采样。 听起来好像很简单&#xff0c;对一些简单的分布函数确实如此&#xff0c;比如&#xff0c;均匀分布、正太分布&#xff0c;但只要分布函数稍微复杂一点&#…