HTTP缓存问题

问题描述

首先,请看看robbin这文章: http://www.iteye.com/topic/462476然后,问题:如果请求的网页没有改变,则直接给客户端返回 304 Not Modified 信息, 那这个用java编程怎么实现的呢(怎么修改HTTP响应头信息)?还有,我感觉tomcat在返回给客户端资源信息时,根本就没有添加 HTTP 响应头信息,直接给客户端返回HTML内容,为什么呢?是通过response吗?

解决方案

一般来说,http的响应头都由tomcat给你处理好了.比如:你请求一个不存在的页面,服务器(tomcat)会返回一个http状态码404如果请求的网页没有改变,则直接给客户端返回 304 Not Modified 信息,这个如果是静态页面的话(html),服务器也会直接处理了.对于动态页面(jsp),可以使用response的方法设置响应头.典型的响应头如下:DateThu, 11 Nov 2010 14:42:47 GMTServerApache/2.0.63 (Unix)X-Powered-ByPHP/5.2.9X-Pingbackhttp://kenwublog.com/xmlrpc.phpLink<http://kenwublog.com/?p=1459>; rel=shortlinkx-ua-compatibleIE=EmulateIE7Keep-Alivetimeout=15, max=100ConnectionKeep-AliveTransfer-EncodingchunkedContent-Typetext/html; charset=UTF-8给客户端返回 304 Not Modified 信息,是通过设置http状态码来实现的:response.setStatus(304);就可以了.至于感觉不到响应头,是因为服务器有一些默认的响应头,所以感觉不到
解决方案二:
可以重新response,去设置信息,返回到客户端。HttpServletResponseWrapper为我们实现对response对象的后处理提供了帮助——你只需编写一个 HttpServletResponseWrapper的子类,加入自己的功能实现(修饰器模式)。那么子类化 HttpServletResponseWrapper都需要重写那些方法呢? 1、获取response对象,并将输出存放在自定义的流里面,那么关于输出流(outputStream、writer)的操作都是需要重写的了: 1)以流的方式获取输出——重写getOutputStream() 2)以字符方式获取输出——重写getWriter() 3)刷新流——重写flushBuffer() 4)重置流——重写reset() 然后加入新增的获取输出数据的方法就ok了。 2、定义response包装器WapperedResponse继承HttpServletResponseWrapper public class WapperedResponse extends HttpServletResponseWrapper { private ByteArrayOutputStream buffer=null; private ServletOutputStream out=null; private PrintWriter writer=null; public GZipResponse(HttpServletResponse resp) throws IOException{ super(resp); buffer=new ByteArrayOutputStream();//真正存储数据的流 out=new WapperedOutputStream(buffer); writer=new PrintWriter(new OutputStreamWriter(buffer,this.getCharacterEncoding())); } //重载父类获取outputstream的方法 @Override public ServletOutputStream getOutputStream()throws IOException{ return out; } //重载父类获取writer的方法 @Override public PrintWriter getWriter() throws UnsupportedEncodingException{ return writer; } //重载父类获取flushBuffer的方法 @Override public void flushBuffer()throws IOException{ if(out!=null){ out.flush(); } if(writer!=null){ writer.flush(); } } @Override public void reset(){ buffer.reset(); } public byte[] getResponseData()throws IOException{ flushBuffer();//将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 return buffer.toByteArray(); } //内部类,对ServletOutputStream进行包装 private class WapperedOutputStream extends ServletOutputStream{ private ByteArrayOutputStream bos=null; public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException{ bos=stream; } @Override public void write(int b) throws IOException{ bos.write(b); } } } 那么Servlet容器通过调用getOutputStream()方法获得的输出流将是我们自定义的包装流WapperedOutputStream。 3、现在就可以在过滤器中使用WapperedResponse进行对response包装、处理了。 public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletResponse resp=(HttpServletResponse)arg1; WapperedResponse wapper=new WapperedResponse(resp); arg2.doFilter(arg0, wapper); byte[] b1=wapper.getResponseData(); //do something with b1 here byte[] b2=...; //输出处理后的数据 ServletOutputStream output=arg1.getOutputStream(); output.write(b2); output.flush(); }
解决方案三:
你可以为要请求的页面设置一个过滤器,在里面检查页面内容是否被编辑过(不知道你怎么检查的),如果内容未变,就直接在response里写入响应头信息。好像是用response.setStatus()方法设置状态码的。

时间: 2024-08-02 00:08:05

HTTP缓存问题的相关文章

固态硬盘做系统盘和做缓存盘有什么区别

  固态硬盘做系统盘和做缓存盘有什么区别          用固态硬盘直接做缓存盘不同于直接用固态硬盘做系统盘直接在固态硬盘上读取数据,固态硬盘做缓存盘的时候是根据用户经常访问的数据,将这一部分数据保存到固态硬盘上方便下次读取的时候快速读取而已,其作用类似硬盘的内存,只不过这块内存的数据并不会伴随关机而自动清空.         推荐阅读:让SSD速度飞起来 固态硬盘优化技巧大全  因此综上所述,最立竿见影的方法就是直接将固态硬盘做系统盘,并用剩余的容量安装游戏或者其他常用软件,这样收益是最明显

[Android] 缓存机制

移动开发本质上就是手机和服务器之间进行通信,需要从服务端获取数据.反复通过网络获取数据是比较耗时的,特别是访问比较多的时候,会极大影响了性能,Android中可通过缓存机制来减少频繁的网络操作,减少流量.提升性能. 实现原理 把不需要实时更新的数据缓存下来,通过时间或者其他因素 来判别是读缓存还是网络请求,这样可以缓解服务器压力,一定程度上提高应用响应速度,并且支持离线阅读.  Bitmap的缓存 在许多的情况下(像 ListView, GridView 或 ViewPager 之类的组件 )我

实战给AW_Blog插件添加缓存(续)

两年前的文章(实战给AW_Blog插件添加缓存)描述了一个Block Cache的实例,最近发现代码其实写的有点累赘,后台保存时自动触发刷新缓存并不需要自己去写刷新的动作,系统原生的Model继承类Mage_Core_Model_Abstract里已经有实现这个动作的代码,只需要简单的配置下变量就能实现.修改后的方案如下(Block类的所需修改代码不变) 打开AW_Blog_Model_Post这个文件,在头部定义一个常量,再定义一个变量 const CACHE_TAG = 'aw_blog';

页面的缓存与不缓存设置

HTML的HTTP协议头信息中控制着页面在几个地方的缓存信息,包括浏览器端,中间缓存服务器端(如:squid等),Web服务器端.本文 讨论头信息 中带缓存控制信息的HTML页面(JSP/Servlet生成好出来的也是HTML页面)在中间缓存服务器中的缓存情况.       HTTP协议中关于缓存的信息头关键字包括Cache-Control(HTTP1.1),Pragma(HTTP1.0),last-Modified,Expires等.       HTTP1.0中通过Pragma 控制页面缓存

android-Android 如何实现垃圾清理、缓存清理?

问题描述 Android 如何实现垃圾清理.缓存清理? Android 如何实现垃圾清理.缓存清理?要删除什么哪些文件或者要怎么做?在下想写一个一键清理应用,可不知从何下手.谢谢! 解决方案 如果是你自己的应用,把文件放在getCacheDir()中的话,可以删除那些文件.用常用的文件I/O接口. 但是如果是其他应用的文件,没有权限修改或删除的. 解决方案二: android 垃圾收集在不定时间下发生,并由Dalvik虚拟机决定什么时候回收垃圾,显示调用System.gc()可以提醒虚拟机,收集

app-Android 文件缓存策略

问题描述 Android 文件缓存策略 需求是这样的: 打开Android app访问服务器端的页面,第一次访问服务端,第二次就可以直接读缓存:在服务端有数据更新的时候,可以定时的更新,清除缓存,重新访问服务端的页面,谁有完整的demo(ps:使用文件缓存的策略),谢谢! 解决方案 莫有人知道吗?急用,有个案例参考下

火狐浏览器缓存路径的更改问题

  安装好火狐浏览器后,通过在 Firefox 地址栏输入 about:cache 可以看到Firefox 的默认磁盘缓存目录是在 Windows 用户配置文件夹里面.而用户配置文件一般是在系统安装盘里面,为了不影响系统的运行速度及系统盘的碎片空间占用,一般可以设置浏览器的缓存文件的存储路径. 设置磁盘缓存目录放入其他目录: 地址栏输入 about:config,右键新建两个字符串.一个名为: "browser.cache.disk.parent_directory" (硬盘缓存),然

反射 程序集-成功添加程序集到缓存中 但assmbly找不到该文件

问题描述 成功添加程序集到缓存中 但assmbly找不到该文件 成功将DLL添加到程序集中了.但是C:Windowsassembly目录下找不到该DLL

计算机体系结构6_缓存结构

一,缓存结构         下图为一个n-way set-associative cache 结构图:                                                               缓存组织为cache line数组的形式,每一个cache line由三部分组成,内存数据,tag,其他信息.                     多个cache line一行,组成一个set,一列cache line为way,在n-way set-associat

清除css、js缓存的问题

问题描述 清除css.js缓存的问题 为了解决缓存问题,引进hash,请问以下两种方式效果有不同吗,哪种更好 1 加参数后缀 style.css?85d5fbce27dd2d50e2e2 2 改文件名 style_85d5fbce27dd2d50e2e2.css 解决方案 第一个好点吧,第二个还要多一个步骤修改文件名. 不过有些时候还得看服务端配置,要是有些服务器端是居于文件名进行缓存可能无法更新缓存内容 解决方案二: 如果改完,清楚缓存后页面还没变化 有一个办法: ?ver=0.1">