Java使用GZIP进行压缩和解压

附加java源码包下载地址

网页GZIP压缩可以提高网页浏览速度,无论是之前在如何做网站课程中说的精简代码、图片无损压缩都不如启用Gzip来的实在。只要服务器开启了GZIP压缩,那么浏览器接收的就是压缩的内容,而开启网页压缩的目的是为了提高网络的传输速度,但会占用一些CPU资源,因为压缩内容需要CPU工作。

先贴出代码
package cn.filter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
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.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class GzipFilter implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		MyResponse resp = new MyResponse((HttpServletResponse)response);
		//PS:MyResponse extends HttpServletResponseWrapper不会输出页面内容(因为重写了getOutputStream和getWriter()为了得到字符流) 而 ServletResponse response会(resp不会有内容,response有内容)。
		chain.doFilter(request, resp);//通过这句话MyResponse得到字符流,不会输出页面内容(因为重写了getOutputStream和getWriter()为了得到字符流)
		//MyResponse得到字符流,下面就可以处理GIZP压缩了、就可以自己输出页面内容了
		ByteArrayOutputStream bout = resp.getBout();
		byte[] srcBytes = bout.toByteArray();//原来的字节
		//下面进行压缩:
		ByteArrayOutputStream bout2=new ByteArrayOutputStream();
		GZIPOutputStream gout=new GZIPOutputStream(bout2);
		gout.write(srcBytes);//把原数据写入gout---bout2
		gout.close();
		byte[] descBytes=bout2.toByteArray();
		//输出之前告诉客户端:我们的数据是gzip格式,然后输出
		HttpServletResponse httpResp=(HttpServletResponse) response;
		httpResp.setHeader("Content-Encoding", "gzip");
		httpResp.setContentLength(descBytes.length);
		httpResp.setContentType("text/html;charset=utf-8");
		OutputStream out=httpResp.getOutputStream();//拿到字节流,必须是字节流
		out.write(descBytes);
	}

	@Override
	public void destroy() {
	}
}
class MyResponse extends HttpServletResponseWrapper{
	private ByteArrayOutputStream bout;
	PrintWriter pw = null;
	public MyResponse(HttpServletResponse response) {
		super(response);
		bout=new ByteArrayOutputStream();
	}
	public ByteArrayOutputStream getBout() {
		//如果是字符数据
		if(pw!=null){
			pw.close();//要关流刷新
		}
		return bout;
	}
	//在这里重写getOutputStream和getWriter方法 这两个方法在GET浏览器数据时会自动调用
	//二进制数据
	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		return new MyOutputStream(bout);
	}
	//字符数据
	@Override
	public PrintWriter getWriter() throws IOException {
		pw=new PrintWriter(new OutputStreamWriter(bout,"utf-8"));//用套接流来进行套接 因为(bout,"utf-8")是字节而printWriter是字符 要套接成字符用OutputStreamwriter
		return pw;
	}

}

//ServletOutputStream 提供将二进制数据发送到客户端的输出流
class MyOutputStream extends ServletOutputStream{
	private ByteArrayOutputStream bout;

	public MyOutputStream(ByteArrayOutputStream bout) {
		this.bout = bout;
	}

	@Override
	public void write(int b) throws IOException {
		bout.write(b);//把数据写入bou字节流里面
	}

}

逻辑
1。把chain.doFilter(request, response);的response 继承
HttpServletResponseWrapper
因为在
HttpServletResponseWrapper可以重写getWriter,getOutputStream方法。
通过这些方法获得响应的数据。并且写入
ByteArrayOutputStream bout
2。通过
ByteArrayOutputStream bout=resp.getBout();
		byte[] srcBytes=bout.toByteArray();//这是源数据
    获取源数据。
3 进行数据压缩 并且输出
//下面进行压缩:
		ByteArrayOutputStream bout2=new ByteArrayOutputStream();
		GZIPOutputStream gout=new GZIPOutputStream(bout2);
		gout.write(srcBytes);//把原数据写入gout---bout2
		gout.close();
		byte[] descBytes=bout2.toByteArray();
		//输出之前告诉客户端:我们的数据是gzip格式,然后输出
		HttpServletResponse httpResp=(HttpServletResponse) response;
		httpResp.setHeader("Content-Encoding", "gzip");
		httpResp.setContentLength(descBytes.length);
		httpResp.setContentType("text/html;charset=utf-8");
		OutputStream out=httpResp.getOutputStream();//拿到字节流,必须是字节流
		out.write(descBytes);
然后在web.xml配置拦截

gzip
cn.controller.GzipFilter




gzip
*.jsp


gzip
*.css


gzip
*.js


gzip
*.jpg


可以下载 http://download.csdn.net/download/sinat_36596988/10232572

你可能感兴趣的:(Java使用GZIP进行压缩和解压)