一般情况下,浏览器都会缓存已经访问过的页面内容,关于如何禁止浏览器缓存的介绍,在网上到处都有相关的文章,但是,关于浏览器如何利用缓存,如何处理缓存的讲解,却鲜有人谈及

.浏览器在访问已缓存过的资源时,它在什么情况下会向服务器发送请求?在什么情况下根本就不向服务器发送请求.这与浏览器的缓存设置有关!但是,由于几乎所有人的浏览器都是采用的默认设置,所以,重点应该放在分析浏览器的默认缓存设置的研究上.

浏览器缓存内幕与getLastModified方法:
  在HttpServlet类中定义了一个getLastModified方法,其完整语法定义如下:
      protected long getLastModified(HttpServletRequest req)
  其中的返回值表示自1970年1月1日的0点0分0秒开始计算的一个毫秒数,HttpServlet类中定义的getLastModified方法总是返回一个负数,在HttpServlet子类中可以对这个方法进行覆盖,以便返回一个代表当前输出的响应内容的修改时间,HttpServlet类的service方法可以根据这个返回值在响应消息中自动生成Last-Modified头字段。
  一般情况下,浏览器都会缓存已经访问过的页面内容,getLastModified方法的返回值可以影响浏览器如何处理和利用缓存内容。在详细了解getLastModified方法的应用之前,应该先对浏览器的缓存机制有所了解。单击IE浏览器的“工具”à“Internet选项”菜单,打开“Internet选项”对话框,接着再单击“常规”选项卡中的“Internet临时文件”栏中的“设置”按钮,打开如图4.16所示的“设置”对话框。

还可以看到,其“检查所存网页的较新版本”功能项的设置值有4个选项,只要先单击“设置”对话框标题栏中的问号按钮,然后再单击相应的选项,就可以看到每个选项的作用和意义:

“每次访问此页时检查”选项表示浏览器每次访问一个页面时,不管浏览器是否缓存过此页面,都要向服务器发出访问请求。这种设置的优点是实时性很强,肯定能够访问到网页的最新内容,但是如果网页内容很少更新,这种设置的访问效率就比较低了。 
“每次启动Internet Explorer时检查”选项表示在浏览器的每次启动运行期间,在第一次访问一个页面时,不管浏览器是否缓存过此页面,都要向服务器发出访问请求,但是在浏览器的本次启动运行期间对该页面的后续访问,浏览器将不再向服务器发出访问请求,而是直接使用缓存中的内容。这种设置具有较高的访问效率,同时也兼顾了较好的实时性,它可以保证每次启动浏览器后看到的都是最新的网页内容。 
“自动”选项与“每次启动Internet Explorer时检查”选项的功能相似,只是对图像的访问有所不同,如果随着时间的推移,浏览器发现网页上的图像更新并不频繁,这样,即使浏览器在对某个已缓存的图像执行本次启动运行以来的第一次访问时,它也不一定会向服务器发出访问请求,而是干脆直接使用缓存中的内容。“自动”选项是浏览器的默认设置,所以,几乎所有人的浏览器都是按照这种方式工作的,这个选项的作用和意义应该成为读者熟悉的重点。 
“不检查”选项表示浏览器不管在什么情况下访问一个页面时,只要能够在本地找到此页面的缓存信息,浏览器就不会向服务器发出访问请求,而是直接使用缓存的内容。这种设置的优点是访问效率很高,但是如果服务器端的网页内容更新后,浏览器看到的内容很可能是过期的内容。

浏览器将根据响应消息中是否包含Last-Modified头字段来进行处理,如果响应消息中没有包含Last-Modified头字段,它将在每次访问此页面时都向服务器发出访问请求,否则,它仅在每次启动运行后的第一次访问此页面时才向服务器发出访问请求,而在启动运行期间对此页面的后续访问都不再向服务器发出访问请求。

响应消息中的Last-Modified头字段可用于指定响应内容的最后更新时间,当客户机缓存此文档内容后,它在以后的请求消息中将根据Last-Modified头字段指定的时间来生成If-Modified-Since请求头字段,以指出缓存文档的最后更新时间。只有文档的修改时间比If-Modified-Since请求头指定的时间新时,服务器才会返回文档内容。如果自从If-Modified-Since指定的时间以来,网页内容没有发生修改,服务器将返回一个304(Not Modified)状态码来表示浏览器缓存的版本是最新的,而不会向浏览器返回文档内容,浏览器则继续使用以前缓存的内容。通过这种方式,可以在一定程度上减少浏览器与服务器之间的通信数据量,从而提高了通信效率。

HttpServlet类为If-Modified-Since请求头和Last-Modified头字段的这种应用提供了处理机制,当继承了HttpServlet类的Servlet程序接收到一个GET方式的访问请求时,HttpServlet中重载的service方法在调用doGet方法之前,它还将调用getLastModified方法,并根据getLastModified方法的返回值来决定是否调用doGet方法和在响应消息中是否生成Last-Modified头字段,具体规则如下:

当getLastModified方法返回一个负数时,不管请求消息中的情况怎样,service方法都将直接调用doGet方法来生成响应内容,这正是HTTPServlet类中定义的getLastModified方法的行为; 
当getLastModified方法返回一个正数,且请求消息中没有包含If-Modified-Since请求头时(这往往出现在第对某个资源的第一次访问时),或者请求消息中包含的If-Modified-Since请求头中的时间值比getLastModified方法返回的时间值旧时,service方法将根据getLastModified方法的返回值生成一个Last-Modified头字段,然后调用doGet方法生成响应内容; 
当getLastModified方法返回一个正数时,且请求消息中包含的If-Modified-Since请求头中的时间值比getLastModified方法返回的时间值新或者与之相同时,service方法将不调用doGet方法,而是向浏览器返回一个304(Not Modified)状态码表示浏览器可以使用其以前缓存的内容。

动手体验:揭开浏览器缓存的奥秘

编写一个名为CacheServlet的Servlet程序,在其doGet方法中向浏览器和Tomcat的命令行窗口中都打印出当前的时间值,getLastModified方法也是向Tomcat的命令行窗口中打印出当前的时间值和返回当前时间值,这里先将getLastModified方法注释掉,如例程4-9所示。

例程4-9  CacheServlet.java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class CacheServlet extends HttpServlet
{
   public void doGet(HttpServletRequest request,
     HttpServletResponse response) throws ServletException, IOException
   {
      PrintWriter out = response.getWriter();
      long now = System.currentTimeMillis();
      out.println("doGet:" + now);
      System.out.println("doGet:" + now);
   }
 
    /*protected long getLastModified(HttpServletRequest req)
     {
        long now = System.currentTimeMillis();
        System.out.println("getLastModified:" + now);
        return now;
       }*/
}

J2EEweb开发中的缓存问题的研究的更多相关文章

  1. PHP开发中的缓存技术汇总

    在PHP开发中,出于对网站服务器负载的考虑,往往需要对页面.数据等内容进行缓存处理,下面就来看看,在PHP开发中有哪些缓存方式吧. 1.页面部分缓存该种方式,是将一个页面中不经常变的部分进行静态缓存, ...

  2. web开发中对缓存的使用

    很久没有发表随笔了,最近工作不是太忙,抽点时间 给大家谈谈缓存吧 ; 在我从事web开发的几年实践中  接触了缓存技术 也是比较多的,在最初的 项目当中 我们用到 hibernate 的 一二级缓存, ...

  3. 开发中tomcat缓存问题

    tomcat-清除缓存 方法一:  conf/server.xml文件  Context path中间加上reloadable="true"  例如:<Context pat ...

  4. JavaWeb项目开发中eclipse缓存问题

    学习Java快2年了 有时候改完代码启动tomcat测试时,新代码不生效,这可能就是缓存问题. 所以平时就用以下几个方法解决,如果还是解决不了,就找老师吧! 1.清理项目 2.移除项目,清理tomca ...

  5. 谈谈MVC项目中的缓存功能设计的相关问题

    本文收集一些关于项目中为什么需要使用缓存功能,以及怎么使用等,在实际开发中对缓存的设计的考虑 为什么需要讨论缓存呢? 缓存是一个中大型系统所必须考虑的问题.为了避免每次请求都去访问后台的资源(例如数据 ...

  6. 【初码干货】使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践

    提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OS ...

  7. C++研究之在开发中你可能没有考虑到的两个性能优化

     1:多余的存储引用导致性能减少. 2:利用局部性提高程序性能: 先来说说引用是怎么减少程序性能.个人觉得减少程序性能主要有两个原因,一是数据结构选择不合理,二是多层嵌套循环导致部分代码被多余反复 ...

  8. django开发中利用 缓存文件 进行页面缓存

    首先我们先来了解下浏览器的缓存 浏览器缓存机制 Cache-control策略 Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是 ...

  9. Java开发微信公众号(五)---微信开发中如何获取access_token以及缓存access_token

    获取access_token是微信api最重要的一个部分,因为调用其他api很多都需要用到access_token.比如自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等在请求的时候 ...

随机推荐

  1. iOS应用程序状态图

    理解应用的状态对于我们开发iOS大有裨益. 当前应用所处什么状态,什么促使它在各个状态间进行过渡,你的代码又是如何 唤醒这些过渡,等等等等. 先请看下图: 1. 当应用出于非运行状态时,它处于图中的& ...

  2. jquery hasClass()、is()

    一..hasClass() hasClass()方法是用来检查被选择的元素是否包含指定的class名,其语法: $(selector).hasClass("className"); ...

  3. RPi Desktop盒子安装与服务配置

    批量安装配置盒子时候,可以先安装一个,其余的从这台copy过去. 之前的部分shell记录在本地,记录如下,以免忘记.下次可直接cp执行即可: Step1, 创建用户/组 sudo groupadd ...

  4. Linux开机自动启动某一程序

    Linux开机启动程序详解我们假设大家已经熟悉其它操作系统的引导过程,了解硬件的自检引导步骤,就只从Linux操作系统的引导加载程序(对个人电脑而言通常是LILO)开始,介绍Linux开机引导的步骤. ...

  5. 获取自增ID

    方法一(一般不使用,多线程可能不准确) SELECT MAX(id) FROM table 方法二(一般使用这个) SELECT LAST_INSERT_ID()

  6. vue重要特性

    重要特性 自定义input组件 动态组件 递归组件 slot 作用域slot 异步组件 内联模板 子组件索引 进阶 自定义指令 状态管理vuex 单文件组件 生产部署 路由 xxx

  7. nginx做负载均衡,验证码总是不对(2台服务器)

    问题原因:页面中有错误链接,导致跳转到另一台服务器,验证码显示的确是刚开始访问的 (有的静态文件一边没有,就需要去另外一边找,然后就跳了.) 解决方法:把静态文件都提取到了nginx上就解决了.

  8. Kafka 跨集群同步方案(转)

    来自:http://tangzhaohui.net/524 Kafka 跨集群同步方案——Kafka内置的MirrorMaker工具 该方案解决Kafka跨集群同步.创建Kafka集群镜像等相关问题, ...

  9. 不同版本的tomcat下载路径

    1.由于安全问题,有些tomcat存在漏洞.为了升级要么修复漏洞,要么就直接升级tomcat. 一般升级tomcat比较省事.但是找到相应版本的tomcat比较难,所以还是要自己寻找对应的tomcat ...

  10. mint 设置无线 AP

    所需软件: sudo apt-get install hostapd 1. 创建 hostapd 的 configure 文件 新建 hostapd.conf 文件,存放位置任意,与后面修改的路径一致 ...