`

让servlet支持浏览器缓存

 
阅读更多

大家都知道IE等浏览器支持缓存,并且缓存策略可配置,这样可以极大提高访问服务器的性能,对于一些如JS脚本、CSS文件、图片等静态资源,已经缺省被支持,但是对于自定义Servlet,则默认情况下不支持缓存,这

是什么原因呢?如何让自定义Servlet也支持缓存呢?
    首先来了解下浏览器的缓存机制:对于所有的HTTP Get请求,浏览器会先检查客户端本地缓存是否存在,如果存在,则会在请求头中包含If-Modified-Since头信息,这个Header的值是本地缓存中资源的最后修改时间,服务端通过访问这个头信息和服务器上资源的最后修改时间进行比较,如果服务器端时间更新,则表示资源被修改了,需要重新下载,会调用doGet方法当作正常的Get请求处理,如果服务器端资源最后修改时间不大于客户端的最后修改时间,则表示资源没有修改,直接返回一个304的状态码,表示请浏览器使用自己缓存中的就行了,从而实现了缓存,减少了网络传输,提高了性能。
    但是不是这样的处理在每次请求时都会做呢?答案是否定的!其实这种处理是每个浏览器进程对相同的请求只会做一次,第一次检查完版本后对于后续相同的请求根本不会向服务器发任何请求,直接从客户端缓存中取资源。这样就更进一步提高了性能。
    好了,明白了浏览器的缓存原理后,我们来看下如何让我们自己写的Servlet也能够被浏览器识别并缓存呢?其实这种处理在Servlet的基类中已经处理好了,实现者只需要提供一个最后修改时间的机制就行了。先来看下

基类(HttpServlet)中是如何实现的(反编译代码):
 

  1. protected void service(HttpServletRequest req, HttpServletResponse resp)  
  2.         throws ServletException, IOException  
  3.     {  
  4.         String method = req.getMethod();  
  5.         if(method.equals("GET"))  
  6.         {  
  7.             long lastModified = getLastModified(req);  
  8.             if(lastModified == -1L)  
  9.             {  
  10.                 doGet(req, resp);  
  11.             } else  
  12.             {  
  13.                 long ifModifiedSince = req.getDateHeader("If-Modified-Since");  
  14.                 if(ifModifiedSince < (lastModified / 1000L) * 1000L)  
  15.                 {  
  16.                     maybeSetLastModified(resp, lastModified);  
  17.                     doGet(req, resp);  
  18.                 } else  
  19.                 {  
  20.                     resp.setStatus(304);  
  21.                 }  
  22.             }  
  23.         } else  
  24.         ......  
  25.     }  

 

从上面的代码实现就可以看出,取最后修改时间是调用getLastModifyed方法,这是一个保护的方法,定义如下:
protected long getLastModified(HttpServletRequest req)
    {
        return -1L;
    }
所以要想Servlet能够支持浏览器缓存,只需要把这个方法重新实现为返回正确的最后修改时间就行了。
举个例子:
我们实现一个Servlet,产生一个服务器端的Java类的客户端JavaScript代理,这被一些Ajax框所使用,
整个类如下所示,覆盖实现了getLastModifyed方法:

  1. public class RemoteServlet extends HttpServlet {  
  2.     public RemoteServlet() {  
  3.     }  
  4.     /** 
  5.      * 记录类的最近访问时间. 
  6.      */  
  7.     private static final Map DATEMAP=new HashMap();  
  8.     /* 
  9.      * (non-Javadoc) 
  10.      *  
  11.      * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, 
  12.      *      javax.servlet.http.HttpServletResponse) 
  13.      */  
  14.     protected void doGet(HttpServletRequest request,  
  15.             HttpServletResponse response) throws ServletException, IOException {  
  16.         response.setContentType("application/x-javascript;charset=GBK");  
  17.         String path = request.getServletPath();  
  18.         int index = path.lastIndexOf('/');  
  19.         path = path.substring(index + 1);  
  20.         PrintWriter writer = response.getWriter();  
  21.         String scriptStr = "";  
  22.         try {  
  23.             //如果不存在,则添加当前时间   
  24.             if(!DATEMAP.containsKey(path)){  
  25.                 DATEMAP.put(path,new Date());  
  26.             }  
  27.             scriptStr = ClassToRemoteUtil.ClassToRemote(path);  
  28.         } catch (Exception e) {  
  29.             if(log.isErrorEnabled()){  
  30.                 log.error(e.getMessage(),e);  
  31.             }  
  32.             scriptStr="alert('产生远程服务代理"+path+"失败:"+e.getMessage()+"');";  
  33.         }  
  34.         writer.write(scriptStr);  
  35.     }  
  36.   
  37.     /** 
  38.      * {@inheritDoc} 
  39.      * @see javax.servlet.http.HttpServlet#getLastModified(javax.servlet.http.HttpServletRequest) 
  40.      */  
  41.     protected long getLastModified(HttpServletRequest req) {  
  42.         String path = req.getServletPath();  
  43.         int index = path.lastIndexOf('/');  
  44.         path = path.substring(index + 1);  
  45.         Date lastModifyDate=(Date)DATEMAP.get(path);  
  46.         if(lastModifyDate==null){  
  47.             lastModifyDate=new Date();  
  48.             DATEMAP.put(path, lastModifyDate);  
  49.         }  
  50.         return lastModifyDate.getTime();  
  51.     }  
  52.   
  53. }  

 

这样处理以后,这个Servlet的所有请求都能够被浏览器缓存支持。这个Servlet处理的请求为http://xxxx.xxxx.xxx.xx:port/xxxx/classfullname.ro,
则所有的.ro请求都可以用到浏览器缓存,从而提高性能。

分享到:
评论

相关推荐

    jsp去除浏览器缓存

    ### jsp去除浏览器缓存详解 #### 一、引言 在Web开发中,为了提高用户体验及页面加载速度,浏览器通常会缓存一部分资源。但有时为了确保用户获取到最新的内容,我们需要禁止或控制浏览器对特定页面的缓存。本文将...

    消除浏览器的301重定向缓存

    来禁止浏览器缓存重定向的结果。 示例 新建一个web工程,命名为redirectTest,点击Finish,新建一个Servlet,如下图点击Next,输入如下图点击Next,如下图点击Finish,则一个Servlet创建完成。点击工程名,按下ALT+...

    禁止浏览器缓存当前文档内容

    【禁止浏览器缓存当前文档内容】 在网页开发中,浏览器缓存机制是为了优化加载速度,但是有时会导致问题,比如服务器端更新的内容无法及时反映到客户端。为了防止这种情况,可以通过设置HTTP响应头来禁止浏览器缓存...

    JavaWeb如何实现禁用浏览器缓存

    以下是一个简单的Java Servlet示例,展示了如何在响应头中设置这三个字段来禁用浏览器缓存: ```java package cn.xxx.Servlet; import java.io.IOException; import javax.servlet.ServletException; import javax...

    浏览器缓存

    在Java开发中,浏览器缓存是一个常见的问题,特别是在动态网页应用中,如JSP。当用户更新了页面上的内容,比如修改了客服人员的头像,但刷新页面后,旧的图像可能仍然显示,这就是浏览器缓存导致的现象。浏览器缓存...

    Web应用与开发作业

    (2)有3个http响应头字段可以禁止浏览器缓存当前页面,它们在Servlet中的示例代码如下。 response.setDateHeader("Expires",-1); response.setHeader("Cache-Control","no-cache"); response.setHeader("Pragma",...

    JSP 开发之Servlet解决网页缓存问题

    浏览器缓存是为了提高用户体验和减少网络流量而设计的,它会自动存储用户访问过的网页内容,当用户再次访问同一页面时,浏览器会直接从缓存中加载数据,而不是重新从服务器请求。然而,在某些情况下,比如动态内容...

    IE页面缓存问题jsp及servlet中的设置

    通过在JSP或Servlet中设置响应头,可以有效地控制浏览器如何处理缓存。 #### 设置响应头 在JSP或Servlet中,可以通过`HttpServletResponse`对象来设置响应头,以告知浏览器不要缓存当前页面。以下是一些常用的响应...

    如何清除tomcat缓存

    无论是手动删除缓存文件、配置`server.xml`文件还是控制浏览器缓存,都是解决缓存问题的有效手段。在实际工作中,根据具体情况选择合适的方法可以提高工作效率,避免因缓存问题导致的应用异常。

    页面的缓存与不缓存设置及html页面中meta的作用

    它涉及到浏览器、中间缓存服务器以及Web服务器之间的交互。本篇将详细阐述如何设置页面的缓存与不缓存,以及HTML页面中`meta`标签的作用。 首先,页面缓存主要通过HTTP协议头信息来控制。HTTP1.0使用`Pragma`字段,...

    j2ee17:servlet01:jsp结束,servlet的配置和生命周期

    6. **工具支持**:在开发Servlet应用时,我们可能会用到各种开发工具,例如IDEA、Eclipse等,它们提供了集成的Servlet和JSP开发环境,包括自动完成、调试和部署功能。标签“工具”可能指的就是这些辅助开发的工具。 ...

    servlet使用MVC设计模式实现cookie缓存和分页显示数据

    本示例中,我们探讨的是如何利用Servlet结合MVC(Model-View-Controller)设计模式来实现cookie缓存以及分页显示数据,这两项功能在实际Web应用中非常常见。 **MVC设计模式**: MVC模式是软件工程中的一种架构模式...

    缓存技术详解

    2. **基于AJAX技术的浏览器缓存**:利用客户端浏览器的缓存机制,减少数据传输量,提高Web应用的响应速度。 通过以上介绍可以看出,缓存技术在Web开发和移动开发中扮演着极其重要的角色,合理地设计和使用缓存可以...

    在Jsp中怎样清空缓存 了解就可以了

    首先,我们要知道JSP中的缓存主要涉及到两个层面:浏览器缓存和服务器端的缓存。 1. **浏览器缓存**:当用户访问一个网页时,浏览器会自动将页面的静态资源(如图片、CSS、JavaScript文件等)存储在本地缓存中,...

    jsp缓存方式

    JSP页面的缓存主要包括两方面:一是服务器端对JSP编译后的Servlet的缓存;二是客户端浏览器对JSP渲染后HTML页面的缓存。这两种缓存方式对于提升用户体验和减轻服务器压力都至关重要。 1. **服务器端缓存**:当JSP...

    com.oreilly.servlet

    10. **性能优化**:通过使用Servlet的异步处理、缓存策略、负载均衡等技术,可以提高Web应用的性能和可伸缩性。 总的来说,`com.oreilly.servlet`库提供的`cos.jar`可能包含了一些方便开发Servlet应用的工具和实用...

    java web Servlet

    * 平台独立:Servlet 可以在任何支持 Java 的平台上运行。 * 高性能:Servlet 的性能非常高,能够满足高并发和高流量的需求。 * 多线程:Servlet 可以以多线程方式运行,提高了服务器的响应速度和处理能力。 * 统一...

    细说servlet_笔记

    - `work`: 缓存编译后的JSP文件和Servlet工作目录。 7. **动态网页技术比较** 不同的动态网页技术如Servlet、JSP、PHP、ASP.NET、ASP各有优缺点,选择取决于性能需求、开发效率和社区支持等因素。 8. **BS与CS...

    jsp 页面缓存

    除了服务器端缓存,还可以结合客户端缓存(如浏览器缓存)来进一步优化。客户端缓存通常依赖于HTTP头信息,服务器通过设置合适的缓存策略,可以让浏览器自动缓存静态资源,如CSS、JavaScript文件和图片。 总结来说...

Global site tag (gtag.js) - Google Analytics