当使用response写数据的时候,将数据写到过滤器的缓冲内,然后再过滤器中拿到数据,帮用户压缩了之后,将数据返回给浏览器,就可以实现全站压缩,用户访问的所有数据都会被压缩,过滤器代码如下所示:
package cn.itcast.web.filter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.zip.GZIPOutputStream; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; public class GzipFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; //将数据进入到缓冲中,然后取出进行压缩 ByteArrayOutputStream bout = new ByteArrayOutputStream(); MyResponse myresponse = new MyResponse(response); chain.doFilter(request, myresponse); //servlet myresponse.getOutputStream MyServletOutputStream.write byte data[] = myresponse.getData(); //拿到的是目标资源想写给浏览器的数据 System.out.println("原始大小:" + data.length); byte gzip[] = gzip(data); response.setHeader("content-encoding", "gzip"); response.setHeader("content-length", gzip.length + ""); response.getOutputStream().write(gzip); } private byte[] gzip(byte[] data) throws IOException { ByteArrayOutputStream bout = new ByteArrayOutputStream(); GZIPOutputStream gout = new GZIPOutputStream(bout); //压缩 gout.write(data); gout.close(); //进底层流 return bout.toByteArray(); //从底层流写数据 } class MyResponse extends HttpServletResponseWrapper{ private HttpServletResponse response; private ByteArrayOutputStream bout = new ByteArrayOutputStream(); private PrintWriter pw; public MyResponse(HttpServletResponse response){ super(response); this.response = response; } @Override public ServletOutputStream getOutputStream() throws IOException { return new MyServletOutputStream(bout); } @Override public PrintWriter getWriter() throws IOException { pw = new PrintWriter(new OutputStreamWriter(bout,response.getCharacterEncoding())); //PrintWriter.writer("中国"); return pw; } //返回缓冲区的数据 public byte[] getData(){ if(pw!=null){ pw.close(); } return bout.toByteArray(); } } class MyServletOutputStream extends ServletOutputStream{ private ByteArrayOutputStream bout; public MyServletOutputStream(ByteArrayOutputStream bout){ this.bout = bout; } //写到缓冲中 @Override public void write(int b) throws IOException { bout.write(b); } } public void destroy() { // TODO Auto-generated method stub } public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } }XML配置如下:
<filter> <filter-name>GzipFilter</filter-name> <filter-class>cn.itcast.web.filter.GzipFilter</filter-class> </filter> <filter-mapping> <filter-name>GzipFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> </filter-mapping>