在服务器向浏览器响应数据的时候,对响应的数据进行压缩,便于传输和提升效率。
实现思路:
1、拦截所有请求
2、获取写出的内容
3、对写出的内容进行压缩
4、将压缩内容返回给浏览器
采用的压缩格式为gzip,浏览器支持。
过滤器:
/**
* Servlet Filter implementation class GlobalGzipFilter
* 实现的全栈压缩
*/
@WebFilter("/*")
public class GlobalGzipFilter implements Filter {
/**
* Default constructor.
*/
public GlobalGzipFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// 重构响应对象
GzipResponse rsp=new GzipResponse((HttpServletResponse)response, new ByteArrayOutputStream());
// pass the request along the filter chain
chain.doFilter(request, rsp);
//获取响应的内容
ByteArrayOutputStream baos=rsp.getOutStream();
System.out.println("压缩之前:"+baos.size()+"字节");
//开始压缩
//创建内存流对象,存储压缩之后的的内容
ByteArrayOutputStream newbaos=new ByteArrayOutputStream();
GZIPOutputStream gzip=new GZIPOutputStream(newbaos);
gzip.write(baos.toByteArray());
gzip.flush();
gzip.close();
System.out.println("压缩之后:"+newbaos.size()+"字节");
HttpServletResponse resp=(HttpServletResponse)response;
//设置消息头,标记内容为gzip
resp.setHeader("Content-Encoding", "gzip");
resp.getOutputStream().write(newbaos.toByteArray());//写出真正的内容
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
//自定义的响应对象
private class GzipResponse extends HttpServletResponseWrapper{
private ByteArrayOutputStream baos;//内存输出字节流
private PrintWriter pw;
public GzipResponse(HttpServletResponse response,ByteArrayOutputStream baos) {
super(response);
this.baos=baos;
// TODO Auto-generated constructor stub
}
//获取响应内容的内存流对象,存储着要响应的数据
public ByteArrayOutputStream getOutStream(){
// TODO Auto-generated method stub
if(pw!=null){
pw.flush();
}
return baos;
}
@Override
public PrintWriter getWriter() throws IOException {
//将响应的内容写出到指定的内存流中
pw=new PrintWriter(new OutputStreamWriter(baos,"UTF-8"));
return pw;
}
}
}