文本压缩过滤器实现

package com.tinysoft.cn;

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;

/**
 * 
 * @author 董乐强 2017-7-30 文本压缩过滤器的实现
 */
public class GzipFilter implements Filter {

	public void init(FilterConfig filterConfig) throws ServletException {
	}

	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		HttpServletRequest request;
		HttpServletResponse response;
		try {
			request = (HttpServletRequest) req;
			response = (HttpServletResponse) resp;
		} catch (Exception e) {
			throw new RuntimeException("non-http request");
		}

		// 要对响应到,浏览器的数据进行压缩,则必须获得拦截到响应到浏览器的数据
		// 所以必须对response进行包装,然后将返回的数据保存到内存流中,进行缓存
		// 从而我们可以从内存流中截取response封装的数据,燃后进行压缩处理之后,返回给浏览器
		MyHttpServletResponse myresponse = new MyHttpServletResponse(response);
		// 我要拦截response对象,则在放行之后,进行拦截
		chain.doFilter(request, myresponse);
		// 要对响应到,浏览器的数据进行压缩,则必须获得拦截到响应到浏览器的数据
		// 所以必须对response进行包装,才可以
		byte b[] = myresponse.getBytes();
		System.out.println("压缩前大小:" + b.length);
		// 将数据压缩到内存流中去
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		GZIPOutputStream gout = new GZIPOutputStream(out);
		gout.write(b);
		gout.close();
		// 从内存流中去压缩数据
		b = out.toByteArray();
		System.out.println("压缩后大小:" + b.length);
		// 通知浏览器正文的压缩格式
		response.setHeader("Content-Encoding", "gzip");
		// 将压缩后的数据写回到浏览器
		response.getOutputStream().write(b);
	}

	public void destroy() {
		// TODO Auto-generated method stub

	}
}

class MyHttpServletResponse extends HttpServletResponseWrapper {
	private HttpServletResponse response;
	// 将response输出到浏览器的数据,先保存到内存流中就行缓存
	private ByteArrayOutputStream baos = new ByteArrayOutputStream();
	// 字符输出流
	private PrintWriter pw;

	public MyHttpServletResponse(HttpServletResponse response) {
		super(response);
		this.response = response;
	}

	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		return new MyServletOutputStream(baos);
	}

	@Override
	public PrintWriter getWriter() throws IOException {
		pw = new PrintWriter(new OutputStreamWriter(baos,
				response.getCharacterEncoding()));
		return pw;
	}

	// 将内存流输出,得到结果
	public byte[] getBytes() {
		try {
			if (pw != null)
				pw.close();
			baos.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return baos.toByteArray();
	}
}

// 在一次进行包装,将数据写到内存流中
class MyServletOutputStream extends ServletOutputStream {
	private ByteArrayOutputStream baos;

	public MyServletOutputStream(ByteArrayOutputStream baos) {
		this.baos = baos;
	}

	@Override
	public void write(int b) throws IOException {
		// 写到内存流中去
		baos.write(b);
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值