问题描述
首先,请看看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()方法设置状态码的。