zoukankan      html  css  js  c++  java
  • 压缩字符流和字节流和全站压缩过滤器

     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 缓冲中了,一并处理了。

  • 相关阅读:
    神经网络之 --- 2012_ Alexnet
    Array.obj : error LNK2001: unresolved external symbol "void __cdecl Test_ultiply(void)" (?Test_ultiply@@YAXXZ)
    学习opencv出现配置错误(一)
    port和interface的区别
    Vivado当中的ooc与global模式
    ADC采样率,符号率
    MATLAB&Simulink的重复方式
    傅里叶变换的对称性质
    AXI总结一
    晶振相关(一)
  • 原文地址:https://www.cnblogs.com/friends-wf/p/3753684.html
Copyright © 2011-2022 走看看