你的位置:首页 > Java教程

[Java教程]数据的压缩1 (51)


1 以下是在某个servlet中对指定的数据进行压缩:

package cn.hongxing.servlet;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.io.PrintWriter;

import java.io.StringReader;

import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class GzipServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse resp)

           throws ServletException, IOException {

       //声明准备被压缩的数据

       String str = "Hello你好Hello你好在内存中声明一Hello你好在" +

              "内存中声明一个Hello你好在内存中声明一个Hello你" +

              "好在内存中声明一个<br/>容器声明准备被压缩获取准备被压缩" +

              "的数据的字节码的数据容器声明准备被压缩获取准备被压缩的数" +

              "据的字节码的数据容器声明准备被压缩获取准备被压缩的数据的" +

              "字节码的数据个容器声明准备被压缩获取准备被压缩的数据的字节码的" +

              "数据在内存中声明一个容器声明准备被压缩获取准备被压缩的数据" +

              "的字节码的数据";

       //2:获取准备被压缩的数据的字节码

       byte[] src = str.getBytes("UTF-8");

       //3:在内存中声明一个容器

       ByteArrayOutputStream destByte = new ByteArrayOutputStream();

       //4:声明压缩的工具流,并设置压缩的目的地为destByte

       GZIPOutputStream zip = new GZIPOutputStream(destByte);

       //5:写入数据

       zip.write(src);

       //6:关闭压缩工具流

       zip.close();

       System.err.println("压缩之前字节码大小:"+src.length);

       //7:获取压缩以后数据

       byte[] dest = destByte.toByteArray();

       System.err.println("压缩以后的字节码大小:"+dest.length);

      

       //8:必须要输出压缩以后字节数组

       resp.setContentType("text/html;charset=UTF-8");

       //9:必须要使用字节流来输出信息

       OutputStream out = resp.getOutputStream();

       //10:通知浏览器。这是压缩的数据,要求浏览器解压

       resp.setHeader("Content-encoding","gzip");

       //11:通知浏览器压缩数据的长度

       resp.setContentLength(dest.length);

       //10:输出

       out.write(dest);

    }

}

2:所有页面*。jsp全部压缩

只要是输出信息,只有两种方式:

       Respoonse.getWriter()..[W1] 输出信息 - 字符流。所有的jsp页面,编译后,都是通过JspWriter方式输出的信息。

              但所有jsp页面都是JspWriter,而jspwriter是对PrintWriter的包装。

Response.getOutputStream() – ―― 字节流。

分析:如果要实现全站的压缩,请先实现对所有servlet中的resp.getWriter输出的数据都压缩

        先实现对一个进行压缩。

第一步:书写一个类Servlet类。正常输出信息


 : resp.,getWriter().print(…..);

public class OneServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

       response.setContentType("text/html;charset=UTF-8");

       PrintWriter out = response.getWriter();

       out.println("Hello你好大家同学");

    }

}

第二步:对这上面的这个类进行拦截-Filter,在拦截过程中包装response

    实现抽像类:HttpServletResponseWrapper -
package cn.hongxin.filter;

import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpServletResponseWrapper;

public class GzipFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest request, ServletResponseresponse,

           FilterChain chain) throws IOException, ServletException{

       //声明MyResponse包装类

       MyResponseresp = new MyResponse((HttpServletResponse) response);

       //放行时,必须要传递自己包装过的类

       chain.doFilter(request, resp);

    }

    public void destroy() {

    }

}

//实现对HttpSerlvetResponse的包装

class MyResponse extendsHttpServletResponseWrapper{

    public MyResponse(HttpServletResponse response) {

       super(response);

    }

}

第三步:为了可以压缩数据,我们必须要拦截getwriter方法

       返回的不是apacheWrtiter对象。

以下是完整的代码:

package cn.hongxing.filter;

public class GzipFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest request, ServletResponseresponse,

           FilterChain chain) throws IOException, ServletException{

       //声明MyResponse包装类

       MyResponseresp = new MyResponse((HttpServletResponse) response);

       //放行时,必须要传递自己包装过的类

       chain.doFilter(request,resp);     

       //目标类调用完成了,返回 以后读取a.txt

       Filefile = new File("d:/a/a.txt");

       //声明一个缓存的字符串对象

       StringBuildersb = new StringBuilder();

       //读取文件

       InputStreamin = new FileInputStream(file);

       byte[] b = new byte[1024];

       int len = 0;

       while((len=in.read(b))!=-1){

           sb.append(new String(b,0,len,"UTF-8"));

       }

       in.close();

    //转成字节开始压缩

       byte[] src = sb.toString().getBytes("UTF-8");

       //声明缓存容器

       ByteArrayOutputStreamdestBytes = new ByteArrayOutputStream();

       //声明压缩流

       GZIPOutputStreamgzip = new GZIPOutputStream(destBytes);

       //压缩数据

       gzip.write(src);

       gzip.close();

       //获取压缩以后数据

       byte[] dest =destBytes.toByteArray();

       System.err.println("压缩之前:"+src.length);

       System.err.println("压缩以后:"+dest.length);

      //输出

       //必须要使用原生 的response

       HttpServletResponseres = (HttpServletResponse) response;

       res.setContentType("text/html;charset=UTf-8");

       OutputStreamout = res.getOutputStream();

       res.setHeader("Content-encoding", "gzip");//必须

       res.setContentLength(dest.length);

       out.write(dest);

    }

    public void destroy() {

    }

}

//实现对HttpSerlvetResponse的包装

class MyResponse extendsHttpServletResponseWrapper{[W8] 

    public MyResponse(HttpServletResponse response) {

       super(response);

    }

    @Override

    public PrintWriter getWriter([W9] ) throws IOException {

       System.err.println("有人想获取输出流");

       PrintWriter out = new PrintWriter[W10] (

              new OutputStreamWriter(

                     new FileOutputStream("d:/a/a.txt"),"UTF-8"));

       return out;

    }

}