压缩响应问题---HttpServletResponse对象增强

在向浏览器发送响应内容时,可以对响应内容进行压缩,将压缩后的内容发送到浏览器,同时通知浏览器发过来的内容是使用何种算法进行压缩的,浏览器再显示时,将以此中方法进行解码。这样可以节省传输带宽,加快响应速度。这里可以利用Filter来实现全站的响应内容压缩问题。但是HttpServletResponse对象本身不具有压缩响应内容的功能,因此可以对其进行功能增强。

HttpServletResponseWrapper是对HttpServletResonse的默认包装类,MyCompressResponse是继承了HttpServletResponseWrapper类的包装类;由于response向浏览器上输出显示内容有两个方法,一个是同通过getOutputStream获取流对象,调用其write方法将数据写入outputStream流中。另一种方法是通过获取getWriter来获取一个PrintWriter的对象,通过其write方法想浏览器写入一个字符串,一个是基于bit流的,一个是基于字符流的。但是response本身这两中方法都是直接向浏览器输出响应内容,本没有对其进行压缩,因此需要对其进行增强。其思想是增强后的方法,将会先把响应内容输出到一个缓存内,对缓存内的内容进行压缩处理,能够后将压缩后的内容输出到浏览器中,同时通知浏览器,接受到的内容是通过什么算法压缩的及内容的大小,这时,浏览器将会根据此来显示响应内容。下面是增强的MyCompressResponse,具体如下:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;

import javax.servlet.ServletOutputStream;
import javax.servlet.ServletResponse;
import javax.servlet.ServletResponseWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class MyCompressResponse extends HttpServletResponseWrapper {
	private HttpServletResponse response; //接受一个response对象,将对其进行增强
	private ByteArrayOutputStream bout = new ByteArrayOutputStream(); //缓存流,所有响应内容将会被输出到此
	private PrintWriter pw; 
	
	public MyCompressResponse(HttpServletResponse response) {
		super(response);
		// TODO Auto-generated constructor stub
		this.response = response;
	}

	/* (non-Javadoc)
	 * @see javax.servlet.ServletResponseWrapper#getOutputStream()
	 */
	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		// TODO Auto-generated method stub
		return new MyOutputStream(bout); //重写getOutputStream方法
	}


	@Override
	public PrintWriter getWriter() throws IOException {
		// TODO Auto-generated method stub
		pw =  new MyPrintWriter(bout, super.getCharacterEncoding()); //重写getWriter方法,同时对其write方法进行增强,write方法可以指定编码方式	
		return pw; 
	}
	
	public byte[] getBuffer(){
		if(pw!=null){
			pw.close();//将数据输出到bout流中
			
		}
		if(bout!=null){
			return bout.toByteArray();//将缓存返回
		}
		
		return null;
	}
	
}

class MyOutputStream extends ServletOutputStream{
	private ByteArrayOutputStream bout;
	
	
	@Override
	public void write(int b) throws IOException {
		// TODO Auto-generated method stub
		bout.write(b); //将响应内容写到bout缓存流中
	}
	
	public MyOutputStream(ByteArrayOutputStream bout){
		this.bout = bout;
		
	}
	
}

class MyPrintWriter extends PrintWriter{
	private  ByteArrayOutputStream bout;
	private String charset;
	
	public MyPrintWriter(ByteArrayOutputStream bout, String charset) {
		super(bout);
		// TODO Auto-generated constructor stub
		this.bout = bout;  //创建一个PrintWriter,指定字符编码方式
		this.charset = charset;
	}

	/* (non-Javadoc)
	 * @see java.io.PrintWriter#write(java.lang.String)
	 */
	@Override
	public void write(String s) {
		// TODO Auto-generated method stub
		try {
			bout.write(s.getBytes(charset)); //根据指定的编码方式,将响应内容写入到bout缓存
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
Filter:

public class MyCompressFilter implements Filter{
	private FilterConfig filterConfig;
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)resp;
		
		MyCompressResponse gzipResp = new MyCompressResponse(response);
		//使用gzipResp进行放行
		chain.doFilter(request, gzipResp);
		
		byte[] out = gzipResp.getBuffer(); //获取缓存内容
		
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			GZIPOutputStream gout = new GZIPOutputStream(bout);
			gout.write(out);
			gout.close(); //将缓存内容写入到使用GZIP方式压缩的流中
			
			byte[] gzip = bout.toByteArray();
			System.out.println("length:"+out.length);//通知浏览器响应内容的压缩方式及内容长度
			response.setHeader("content-encoding", filterConfig.getInitParameter("encoding"));
			response.setContentLength(gzip.length);
			response.getOutputStream().write(gzip); //使用response将压缩后的内容写到浏览器中
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		this.filterConfig = filterConfig;
	}
	
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值