美文网首页java 成神之路程序员技术干货
Spring mvc HTTP协议之缓存机制

Spring mvc HTTP协议之缓存机制

作者: jijs | 来源:发表于2017-10-12 22:26 被阅读269次

概述

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

    @Override
    public 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()

Paste_Image.png
  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。

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

相关文章

  • Spring mvc HTTP协议之缓存机制

    概述 Spring MVC 支持HTTP协议的 Last-Modified 缓存机制。 在客户端地一次输入URL时...

  • (转)HTTP协议 (四) 缓存

    之前写过一个篇【HTTP协议详解】,这次继续介绍HTTP协议中的缓存机制。HTTP协议提供了非常强大的缓存机制, ...

  • H5页面缓存

    一、协议缓存 http协议缓存机制是指通过 HTTP 协议头里的 Cache-Control(或 Expires)...

  • 浏览器缓存机制

    浏览器缓存机制:浏览器缓存机制,其实主要就是http协议定义的缓存机制(如:Expires;Cache-contr...

  • HTTP协议缓存机制

    缓存相关的请求头 Last-Modified Expires Cache-Control ETag 区别与联系 L...

  • http协议缓存机制

    2.1、学习http协议,理解http请求-响应模式2.2、理解http是应用层协议,它是构建在TCP/IP协议上...

  • http消息头中的缓存控制以及volley和retrofit中的

    缓存控制 浏览器 HTTP 协议缓存机制详解 确实很详细缓存Cache详解 先前对http缓存的主要疑惑在于: 几...

  • http的缓存机制在flask的实现

    http协议有一系列的缓存机制(RFC2616),相关的参数就在协议header中。缓存机制的合理使用可以大大减缓...

  • 浏览器缓存

    浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制(如: Expires; Cache-control等)。但...

  • 浏览器缓存机制

    浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制(如: Expires; Cache-control等)。但...

网友评论

  • 22363437d887:您好。我想请教个问题,按照您写的示例代码每次获取的Modified都是当前毫秒值,那这个缓存机制不就没意义了吗?
    或者说,最后修改时间这种缓存机制具体应该如何保证正确使用?

本文标题:Spring mvc HTTP协议之缓存机制

本文链接:https://www.haomeiwen.com/subject/izwvyxtx.html