首页 > 代码库 > 压缩字符流和字节流和全站压缩过滤器

压缩字符流和字节流和全站压缩过滤器

 1     public static void main(String[] args) throws Exception {
 2         ByteArrayOutputStream bos = new ByteArrayOutputStream();    //字符流
 3         OutputStreamWriter osw = new OutputStreamWriter(bos);
 4         PrintWriter pw = new PrintWriter(osw);
 5         pw.write("helloworld");
 6         pw.flush();
 7         System.out.println(bos.toByteArray().length);
 8 
 9         /*
10          * String s = "abcdefasdfasdfasdfasdfasdfasfd";
11          * System.out.println("未压缩前:" + s.getBytes().length);
12          * 
13          * ByteArrayOutputStream baos = new ByteArrayOutputStream(); //
14          * 创建一个数组输出流.
15          * 
16          * GZIPOutputStream gps = new GZIPOutputStream(baos);//
17          * 向baos字节数组流写入信息时,进行压缩
18          * 
19          * gps.write(s.getBytes());
20          * 
21          * System.out.println("压缩后:" + baos.toByteArray().length);
22          * 
23          * gps.close();
24          * 
25          * byte[] b = new byte[1024]; ByteArrayInputStream bis = new
26          * ByteArrayInputStream(baos.toByteArray());
27          * 
28          * GZIPInputStream gis = new GZIPInputStream(bis);
29          * 
30          * int len = gis.read(b);// 将压缩数组中的信息解压读到b数组中。
31          * 
32          * System.out.println(new String(b, 0, len));
33          * 
34          * gis.close();
35          */
36     }

 

全站压缩过滤器

  1 package cn.itcast.filter;
  2 
  3 import java.io.ByteArrayOutputStream;
  4 import java.io.IOException;
  5 import java.io.OutputStreamWriter;
  6 import java.io.PrintWriter;
  7 import java.util.zip.GZIPOutputStream;
  8 
  9 import javax.servlet.Filter;
 10 import javax.servlet.FilterChain;
 11 import javax.servlet.FilterConfig;
 12 import javax.servlet.ServletException;
 13 import javax.servlet.ServletOutputStream;
 14 import javax.servlet.ServletRequest;
 15 import javax.servlet.ServletResponse;
 16 import javax.servlet.http.HttpServletRequest;
 17 import javax.servlet.http.HttpServletRequestWrapper;
 18 import javax.servlet.http.HttpServletResponse;
 19 import javax.servlet.http.HttpServletResponseWrapper;
 20 //全站压缩过滤器
 21 public class GzipFilter implements Filter {
 22 
 23     public void destroy() {
 24 
 25     }
 26 
 27     public void doFilter(ServletRequest req, ServletResponse resp,
 28             FilterChain chain) throws IOException, ServletException {
 29         HttpServletRequest request = (HttpServletRequest)req;
 30         HttpServletResponse response = (HttpServletResponse)resp;
 31         GzipHttpServletResponse gresponse = new GzipHttpServletResponse(response);
 32         chain.doFilter(request, gresponse);//放行
 33         //压缩代码写在此处
 34         //找一个内存缓冲字节流
 35         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 36         //把数据压缩到缓冲字节流流中
 37         GZIPOutputStream gout = new GZIPOutputStream(baos);
 38         //取出数据:压缩后的
 39         byte b[] = gresponse.getOldBytes();//原始字节
 40         System.out.println("原有数据大小:"+b.length);
 41         
 42         //因为参数是byte b[]数组,所以会调用父类的write(byte[])方法,调用到最后 是write(int b)方法,
 43         //而在父类中声明为抽象的,但是MyServletOutputStream实现了,并且在GzipHttpServletResponse对象中
 44         //在doFilter()会被调用getOutputStream()函数进行操作进行写入输出流
 45         gout.write(b);            
 46         gout.close();//保证所有的数据都进入内存缓存流
 47         
 48         //取出压缩后的数据
 49         b = baos.toByteArray();
 50         System.out.println("压缩后的数据大小:"+b.length);
 51         //输出前一定要告知客户端压缩方式
 52         response.setHeader("Content-Encoding", "gzip");
 53         response.setContentLength(b.length);//告知客户端正文的大小
 54         //用服务器的响应对象输出
 55         ServletOutputStream out = response.getOutputStream();
 56         out.write(b);
 57     }
 58 
 59     public void init(FilterConfig filterConfig) throws ServletException {
 60 
 61     }
 62 
 63 }
 64 class GzipHttpServletResponse extends HttpServletResponseWrapper{
 65     private ByteArrayOutputStream baos = new ByteArrayOutputStream();//用于获取压缩前要输出的数据
 66     private PrintWriter pw;
 67     public GzipHttpServletResponse(HttpServletResponse response){
 68         super(response);
 69     }
 70     //把原始数据封装到一个缓冲流中
 71     @Override
 72     public ServletOutputStream getOutputStream() throws IOException {
 73         return new MyServletOutputStream(baos);
 74     }
 75     
 76     //字符流:把原始数据封装到一个缓冲流中
 77     @Override
 78     public PrintWriter getWriter() throws IOException {            //改写父方法,自己实现PrintWriter
 79         pw = new PrintWriter(new OutputStreamWriter(baos, super.getCharacterEncoding()));//字符流转成字节流编码会丢失
 80         return pw;
 81     }
 82     //返回baos中的缓存数据:原始
 83     public byte[] getOldBytes(){
 84         try {
 85             if(pw!=null){
 86                 pw.close();
 87             }
 88             baos.flush();
 89         } catch (IOException e) {
 90             e.printStackTrace();
 91         }
 92         return baos.toByteArray();
 93     }
 94     
 95 }
 96 class MyServletOutputStream extends ServletOutputStream{
 97     private ByteArrayOutputStream baos;
 98     public MyServletOutputStream(ByteArrayOutputStream baos){
 99         this.baos = baos;
100     }
101     @Override
102     public void write(int b) throws IOException {
103         baos.write(b);
104     }
105 }

 如果调用response.getWriter()和response.getOutputStream()会抛异常,所以不能在代码中都调用,以上方法调用的getOutputStream和getWriter自己覆写了,没有调用servlet本身提供的,所以没有报异常。

把字节流和字符流全都放入ByteArrayOutputStream 缓冲中了,一并处理了。