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

来源:互联网 发布:淘宝十大cos店铺 编辑:程序博客网 时间:2024/06/04 22:47

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

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

//全站压缩过滤器/*将所有的数据进行压缩,然后在输出到浏览器就是重写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;}//字符流:把原始数据封装到一个缓冲流中@Overridepublic 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这个字节数组缓存流中@Overridepublic 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
原创粉丝点击