概述

Spring MVC 支持HTTP协议的 Last-Modified 缓存机制。
1. 在客户端地一次输入URL时,服务器端会返回内容和状态码200, 表示请求成功,同时会添加一个“Last-Modified”属性,表示该请求资源的最后修改时间
2. 客户端第二次请求此URL时,客户端会向服务器发送请求头 “IF-Modified-Since”,如果服务端内容没有变化,则自动返回HTTP304状态码(只返回相应头信息,不返回资源文件内容,这样就可以节省网络带宽,提供响应速度和用户体验)

Spring MVC 中实现示例

UserCacheController.java

@Controller
public class UserCacheController extends AbstractController implements LastModified{private long lastModified = System.currentTimeMillis();protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)throws Exception {List<User> userList = new ArrayList<User>();userList.add(new User("zhangsan", 18));userList.add(new User("wangwu", 16));System.out.println("执行一次,我有缓存");return new ModelAndView("userList", "users", userList);}@Overridepublic long getLastModified(HttpServletRequest request) {//时间戳逻辑,返回最后修改时间,例如if (lastModified == 0L) {lastModified = System.currentTimeMillis();}System.out.println("时间戳:"+lastModified);return lastModified;}
}

Spring MVC 提供的Last-Modified机制的支持,只需要实现LastModified接口,并实现GetLastModified() 方法,每次修改资源的时候,更新下lastModified的值即可。

userList.jsp

<%@page import="java.util.List"%>
<%@page import="cn.com.infcn.bean.User"%>
<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body><%List<User> userList = (List<User>) request.getAttribute("users");for (User user : userList) {%>用户名:<%=user.getUserName()%><br /> 年龄:<%=user.getAge()%><br /><hr><%}%>
</body>
</html>

访问效果


只有第一次执行了Controller,以后访问都没执行Controller。

原理分析

DispatcherServlet.doDispatch()


1. 首先获取 http 请求的method type。
2. 如果method 是 “GET”或“HEAD” 才支持缓存机制
3. 通过 HandlerAdapter.getLastModified() 方法获取 UserCacheController 中的lastModified 的值,最后修改时间。
4. 调用 checkNotModified() 方法验证 http 请求头中的“If-Modified-Since”的时间进行对比,判断页面是否更新过。如果有更新才执行具体的Controller, 没有更新则响应 304 状态码信息(HTTP 304: Not Modified )。

getLastModified()


通过handler的适配器类,然后在调用UserCacheController.getLastModified() 方法获取最后更新时间。

checkNotModified()


1. 调用 validateIfModifiedSince() 方法获取http请求头中的“If-Modified-Since”值,并验证是否修改过。
没有修改过则设置notModified=true,如果修改过则设置notModified=false。
2. 如果 notModified=true,则设置response响应状态码304或412
3. 如果是GET 或 HEAD 请求则添加响应头“Last-Modified”

validateIfModifiedSince()


1. 解析http 请求头中的“If-Modified-Since”值
2. 判断缓存页面是否需要更新。
注:(lastModifiedTimestamp / 1000 * 1000):因为http头中只保存到秒,所以这里把秒后面的置为0。

HTTP 请求响应头分析


通过浏览器F12 可以看出:
1. 每次请求都会携带“If-Modified-Since”信息到服务器验证资源是否需要更新。
2. 服务器响应头中会包含“Last-Modified”信息,访问资源最后修改的日期。

缓存限制条件

并不是所有MappingHandler 方式都支持缓存。
比如:DefaultAnnotationHandlerMapping 就不支持缓存机制。
因为支持注解的Controller中可以有多个请求方法,而每个方法都需要计算文件的最后修改时间,这样LastModified就不适用了。只适用一个Controller中只支持一个请求的HandlerMapping。

AnnotationMethodHandlerAdapter


从代码中可以看出,这个方法永远返回-1。


想了解更多精彩内容请关注我的公众号

本人简书blog地址:http://www.jianshu.com/u/1f0067e24ff8    
点击这里快速进入简书

GIT地址:http://git.oschina.net/brucekankan/
点击这里快速进入GIT

Spring mvc HTTP协议之缓存机制相关推荐

  1. 缓存服务器协议有哪些,HTTP 协议的缓存机制概述

    HTTP 协议的缓存机制涉及到多个请求头字段,而且整个缓存机制的细节行为也存在各种情况的差异,譬如说什么时候访问本地缓存不发送请求,什么时候发送请求查看资源是否更新,获取 response 什么情况下 ...

  2. 8 -- 深入使用Spring -- 5... Spring 3.1 新增的缓存机制

    8.5 Spring 3.1 新增的缓存机制 Spring 3.1 新增了一种全新的缓存机制,这种缓存机制与Spring容器无缝地整合在一起,可以对容器中的任意Bean或Bean的方法增加缓存.Spr ...

  3. Spring MVC的工作原理和机制

    Spring  MVC的工作原理和机制 参考: springMVC 的工作原理和机制 - 孤鸿子 - 博客园 https://www.cnblogs.com/zbf1214/p/5265117.htm ...

  4. 互联网协议 — DNS 缓存机制

    目录 文章目录 目录 DNS 缓存机制 基于缓存的 DNS 域名解析流程 DNS 缓存使用面临的问题 互联网环境缓存应用面临的问题 企业内网缓存应用面临的问题 DNS 缓存在实际应用中的考虑 主动操作 ...

  5. Spring MVC 使用优化建议-缓存URL

    阅读源码的过程中,我们发现Spring MVC 并没有对处理url 的方法进行缓存,也就是说每次都要根据请求url 去匹配Controller 中的方法url,如果把url 和Method 的关系缓存 ...

  6. HTTP 协议 -- 浏览器缓存机制

    浏览器缓存机制 浏览器缓存机制主要是 HTTP 协议定义的缓存机制. HTTP 协议中有关缓存的缓存信息头的关键字有 Cache-Control,Pragma,Expires,Last-Modifie ...

  7. Spring Boot 集成 Redis 实现缓存机制

    本文章牵涉到的技术点比较多:spring Data JPA.Redis.Spring MVC,Spirng Cache,所以在看这篇文章的时候,需要对以上这些技术点有一定的了解或者也可以先看看这篇文章 ...

  8. Spring MVC HelloWorld入门及运行机制 (一)

    完整的项目案例: springmvc.zip 介绍 SpringMVC是一款Web MVC框架. 它跟Struts框架类似,是目前主流的Web MVC框架之一. 文章通过实例来介绍SpringMVC的 ...

  9. Spring Boot Spring MVC 异常处理的N种方法

    默认行为 根据Spring Boot官方文档的说法: For machine clients it will produce a JSON response with details of the e ...

最新文章

  1. xmind 模板_xmind模板打包下载
  2. SVN commit,update用法
  3. 【ARM】Tiny4412裸板编程之LED(二)
  4. Java并发编程—什么是线程?
  5. java如何arraylist_Java如何使用ArrayList类?
  6. 数据结构 - 最小堆最大堆
  7. 自适应滤波实例之噪声抵消
  8. 为什么要给计算机配置IP地址,更改ip地址 为何要重启电脑
  9. 编写第一个OpenACC程序
  10. SDF(Signed-distance-field: 有向距离场)(12): Shadow And AO(WebGL实现)增强立体感
  11. 别在最吃苦的年龄选择了潇洒
  12. 通俗易懂讲解Java线程安全
  13. 高阶篇:4.4)FMEA手册的疑问与不足(个人观点)
  14. 使用VMProtect给软件加壳
  15. 广发99元旅游分期,来一场说走就走的旅行?
  16. arduino mega针脚_Arduino MEGA中文数据手册
  17. 从“断臂求生”到一骑绝尘,航运巨头马士基如何利用区块链技术力挽狂澜?
  18. 北航计算机专硕学硕区别,专硕是什么意思啊?和学硕一样吗?
  19. 历代治国理政者的教科书——金木水火土的起源之书:周朝的统治大法——《洪范》...
  20. Ae 入门系列之二:素材的导入与管理

热门文章

  1. 二十八、Pyspider 爬取链家网
  2. 零基础入门人工智能有门槛吗?学会这些就够了
  3. 10万元奖金语音识别赛进行中!CTC 模型 Baseline 助你轻松上分
  4. 一篇文章理解深度神经网络5个常用激活函数
  5. 点在多边形内外的判断【计算几何】
  6. POJ1185 炮兵阵地 状压DP
  7. 自考计算机原理知识点,09年自考计算机网络实用技术知识点:ATM原理
  8. sqlserver evaluation是什么版本_使用SSMS扫描和查找SQL Server数据库的潜在安全漏洞...
  9. java 计算股票高低点_[转载]股市中常用的一些计算高低点的计算方法
  10. c++ post请求_前端工程师进阶:网络请求方法详解,GET和POST的区别