在进行java web开发的时候,经常会遇到开发的页面会非常的复杂,有时候访问复杂的页面会耗费较多的时间和大量的流量,网络访问效率也势必会降低,此时就需要考虑进行数据压缩。本文就是使用filter实现的对网站所有的页面进行压缩,能进行压缩的取决于浏览器支持对压缩数据的解析(设置消息头Content-Encoding为gzip即可)以及jsp实质就是一个Servlet.
1.相关依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
2.包装类实现
//声明一个reponse的包装类
public class ResponseWrapper extends HttpServletResponseWrapper{
private ByteArrayOutputStream srcByteOutputStream;
private PrintWriter out;
public ResponseWrapper(HttpServletResponse response) {
super(response);
//最好在实例化包装类的时候创建ByteArrayOutputStream,否者较易抛出空指针异常
srcByteOutputStream = new ByteArrayOutputStream();
}
//返回一个ServletOutputSteam的匿名对象.实现witer(int b)方法,将数据写到bytearrayoyutpoutstream.
@Override
public ServletOutputStream getOutputStream() throws IOException {
ServletOutputStream out = new ServletOutputStream() {
//所有的IO最终都是一个字节一个字节写出信息
@Override
public void write(int b) throws IOException {
srcByteOutputStream.write(b);
}
};
return out;
}
//修改增强getWtier方法
@Override
public PrintWriter getWriter() throws IOException {
out = new PrintWriter(new OutputStreamWriter(srcByteOutputStream,"UTF-8"));
return out;
}
//提供一个方法获取原生的数据
public byte[] getSrcByte(){
if(out!=null){
out.close();
}
return srcByteOutputStream.toByteArray();
}
}
3.过滤器
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 {
HttpServletResponse resp = (HttpServletResponse) response;
//1.声明包装类对象
ResponseWrapper rw = new ResponseWrapper(resp);
//2.放行,传递自己包装过的类
chain.doFilter(request, rw);
//3.从rw中读取原生的数据
byte[] srcDatas = rw.getSrcByte();
//4.开始压缩
ByteArrayOutputStream destBytes = new ByteArrayOutputStream();
GZIPOutputStream zip = new GZIPOutputStream(destBytes);
zip.write(srcDatas);
zip.close();
//5.获得压缩以后的数据
byte[] destDatas = destBytes.toByteArray();
System.out.println("压缩以前:"+srcDatas.length);
System.out.println("压缩以后:"+destDatas.length);
//6.设置头
resp.setContentType("text/html;charset=UTF-8");
resp.setContentLength(destDatas.length);
resp.setHeader("Content-Encoding", "gzip");
//7.输出-使用原生的response
OutputStream out = resp.getOutputStream();
out.write(destDatas);
}
@Override
public void destroy() {
}
}
4.配置web.xml
<filter>
<filter-name>gzipFilter</filter-name>
<filter-class>cn.edu.hbut.zw.filter.GzipFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzipFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>