JSP过滤器(Filter)之实现全站数据压缩

一般用于返回给客户端的的数据都要进行压缩后再返回,以减少数据的传输

可以用下面的过滤器进行实现全站数据压缩

//全站压缩过滤器
/*
将所有的数据进行压缩,然后在输出到浏览器
就是重写response对象,然后让其输入的数据存在一个缓冲流中,然后在此过滤器中取出并压缩,再传给客户端
*/
public class GzipFilter implements Filter {

	public void destroy() {

	}

	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)resp;
		//创建一个自己的response,此response对象在原有基础上增加了  以字节数组返回response对象中所有数据的功能
		GzipHttpServletResponse gresponse = new GzipHttpServletResponse(response);
		//放行
		chain.doFilter(request, gresponse);

	//到此次已经执行完了servlet
		
		//压缩代码写在此处
		//创建一个字节数组缓存输出流,用于存放压缩后的数据
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		//创建一个字节压缩输出流,把数据压缩到baos这个字节缓存输出流中
		GZIPOutputStream gout = new GZIPOutputStream(baos);
		
		//取出request对象中的所有数据:压缩前的
		byte b[] = gresponse.getOldBytes();//原始字节数组
		System.out.println("原有数据大小:"+b.length);
		//将原始数据存放到压缩字节输出流中,进行压缩,并将压缩完成的数据存放到baos这个字节数组缓存输出流中
		gout.write(b);
		//刷新
		gout.flush();//保证所有的数据都进入 字节数组缓存输出流
		//关闭压缩流
		gout.close();
		
		//取出压缩后的数据
		b = baos.toByteArray();
		System.out.println("压缩后的数据大小:"+b.length);
		
		//输出前一定要告知客户端压缩方式(用的是当前的response对象)
		response.setHeader("Content-Encoding", "gzip");
		response.setContentLength(b.length);//告知客户压缩后的数据的大小
		//获取当前response对象的字节输出流对象
		ServletOutputStream out = response.getOutputStream();
		//将压缩后的数据 读出到 response对象的字节输出流中
		out.write(b);
		//关闭流
		out.close();
	}

	public void init(FilterConfig filterConfig) throws ServletException {

	}

}
//创建一个自己的response,此response对象在原有基础上增加了  以字节数组返回response对象中所有数据的功能,
//此类继承了HttpServletResponseWrapper这个HttpServletResponse类的适配器
class GzipHttpServletResponse extends HttpServletResponseWrapper{
	//创建一个字节数组缓存流
	private ByteArrayOutputStream baos = new ByteArrayOutputStream();
	//定义一个自己的servletOutputStream 字节输出流对象
	private MyServletOutputStream myOutputStream = null;
	
	//定义一个字节输出转 字符输出的流
	private OutputStreamWriter writer = null;
	//创建一个打印字符输出流
	private PrintWriter pw = null;
	//构造方法
	public GzipHttpServletResponse(HttpServletResponse response){
		super(response);
	}
	//把原始数据封装到一个缓冲流中
	@Override//从写父类中(response)的getOutputStream方法,从而使response.getOutputStream(),方法获取的是我的字节数组缓存流
	public ServletOutputStream getOutputStream() throws IOException {
		if(myOutputStream == null){
			myOutputStream = new MyServletOutputStream(baos);
		}
		//返回给调用者
		return myOutputStream;
	}
	
	//字符流:把原始数据封装到一个缓冲流中
	@Override
	public PrintWriter getWriter() throws IOException {
		if(writer == null){
			//将baos字节数组缓冲流转换成 一个字符输出流
			writer = new OutputStreamWriter(baos, super.getCharacterEncoding());//字节流转成字符流需给一个编码表
		}
		//通过这个字符输出流,创建一个字符打印流,通过此打印字符输出流传入的数据,都会被封装到baos这个字节数组缓存流中
		pw = new PrintWriter(writer);
		//返回给调用者
		return pw;
	}
	
	//返回baos中的缓存的所有数据:原始
	public byte[] getOldBytes(){
		try {
			if(pw!=null){
				pw.close();
			}
			baos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
		//以字节数组返回baos字节数组缓存输出流中的所有数据                                                        
		return baos.toByteArray();
	}
	
}

//创建一个自己的字节缓存流,让写入此流中的数据都写入 到传入的字节数组缓存流中,此类继承了ServletOutputStream适配器
class MyServletOutputStream extends ServletOutputStream{
	private ByteArrayOutputStream baos;
	public MyServletOutputStream(ByteArrayOutputStream baos){
		this.baos = baos;
	}
	//当读取到数据时,就存入baos这个字节数组缓存流中
	@Override
	public void write(int b) throws IOException {
		baos.write(b);
	}
}

 在web.xml中配置文件中,注册此过滤器 
  <filter>
  	<filter-name>GzipFilter</filter-name>
  	<filter-class>AllStieFilter.GzipFilter</filter-class>
  </filter>
  <!-- 配置此过滤器的过滤范围,由于此过滤器是全站过滤器,直接配置/* -->
  <filter-mapping>
  	<filter-name>GzipFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>

通过以上的过滤器,就实现了全站的数据压缩了






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值