Android中使用gzip传递数据

jopen 11年前

HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来减少文件大小,减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。

一.服务端

服务端有2种方式去压缩,一种可以自己压缩,但是更推荐第二种方式,用PrintWriter作为输出流,工具类代码如下

/**     * 判断浏览器是否支持 gzip 压缩     * @param req     * @return boolean 值     */    public static boolean isGzipSupport(HttpServletRequest req) {     String headEncoding = req.getHeader("accept-encoding");     if (headEncoding == null || (headEncoding.indexOf("gzip") == -1)) { // 客户端 不支持 gzip      return false;     } else { // 支持 gzip 压缩      return true;     }    }      /**     * 创建 以 gzip 格式 输出的 PrintWriter 对象,如果浏览器不支持 gzip 格式,则创建普通的 PrintWriter 对象,     * @param req     * @param resp     * @return     * @throws IOException     */    public static PrintWriter createGzipPw(HttpServletRequest req, HttpServletResponse resp) throws IOException {     PrintWriter pw = null;     if (isGzipSupport(req)) { // 支持 gzip 压缩      pw = new PrintWriter(new GZIPOutputStream(resp.getOutputStream()));      // 在 header 中设置返回类型为 gzip      resp.setHeader("content-encoding", "gzip");     } else { // // 客户端 不支持 gzip      pw = resp.getWriter();     }     return pw;    }   

servlet代码如下:
 public void doPost(HttpServletRequest request, HttpServletResponse response)     throws ServletException, IOException {    response.setCharacterEncoding("utf-8");    response.setHeader("Content-Encoding", "gzip");    String ret = "{\"ContentLayer\":{\"title\":\"内容层\"},\"PageLink\":{\"title\":\"页面跳转\"},\"WebBrowser\":{\"title\":\"浏览器\"},"      + "\"InlinePage\":{\"title\":\"内嵌页面\"},\"VideoComp\":{\"title\":\"视频\"},"      + "\"PopButton\":{\"title\":\"内容开关\"},\"ZoomingPic\":{\"title\":\"缩放大图\"},"      + "\"Rotate360\":{\"title\":\"360度旋转\"}}";        PrintWriter pw = new PrintWriter(new GZIPOutputStream(response.getOutputStream()));    pw.write(ret);    pw.close();   }     public void doGet(HttpServletRequest request, HttpServletResponse response)     throws ServletException, IOException {    this.doPost(request, response);   }
在代理软件中跟踪到的数据如下:
‹«VrÎÏ+IÍ+ñI¬L-R²ªV*É,ÉIU²R:rëÄÝM•ju”ÓS}2ó²‘e/m>üì̏ë«@òá©INEùåŨúŸ¬?pàØw¼g^Nf^*ÈTóo™R–™’šïœŸ[€¬àÔåc[ÁÖç8•–”äç¡»nÿª7@  ¢òós3óÒ2“‘Uœþºýè–Ïg÷€Tå—$–¤› +r·¸ðä‡Zh¤†ˆ

实际数据如下:

{"ContentLayer":{"title":"内容层"},"PageLink":{"title":"页面跳转"},"WebBrowser":{"title":"浏览器"},"InlinePage":{"title":"内嵌页面"},"VideoComp":{"title":"视频"},"PopButton":{"title":"内容开关"},"ZoomingPic":{"title":"缩放大图"},"Rotate360":{"title":"360度旋转"}}

二.Android客户端

得到HttpClient代码:

private static DefaultHttpClient getHttpClient() {    DefaultHttpClient httpClient = new DefaultHttpClient();      // 设置 连接超时时间    httpClient.getParams().setParameter(      HttpConnectionParams.CONNECTION_TIMEOUT, TIMEOUT_CONNECTION);    // 设置 读数据超时时间    httpClient.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT,      TIMEOUT_SOCKET);    // 设置 字符集    httpClient.getParams().setParameter("http.protocol.content-charset",      UTF_8);    return httpClient;   }

得到HttpPost:

private static HttpPost getHttpPost(String url) {    HttpPost httpPost = new HttpPost(url);    // 设置 请求超时时间    httpPost.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT,      TIMEOUT_SOCKET);    httpPost.setHeader("Connection", "Keep-Alive");    httpPost.addHeader("Accept-Encoding", "gzip");    return httpPost;   }

访问网络代码:

public static InputStream http_post_return_byte(String url,     Map<String, String> params) throws AppException {    DefaultHttpClient httpclient = null;    HttpPost post = null;    HttpResponse response = null;    StringBuilder sb = null;    StringEntity stringEntity = null;    try {     httpclient = getHttpClient();     post = getHttpPost(url);     sb = new StringBuilder();     if (params != null && !params.isEmpty()) {      Logger.d("In http_post the url is get here");      for (Entry<String, String> entry : params.entrySet()) {       sb.append(entry.getKey())         .append("=")         .append(URLEncoder.encode(entry.getValue(),           HTTP.UTF_8)).append("&");      }      sb.deleteCharAt(sb.lastIndexOf("&"));      Logger.d("In http_post the url is " + url + " and params is "        + sb.toString());      stringEntity = new StringEntity(sb.toString());      stringEntity        .setContentType("application/x-www-form-urlencoded");      post.setEntity(stringEntity);     }       response = httpclient.execute(post);     int statusCode = response.getStatusLine().getStatusCode();     Logger.d("statusCode is " + statusCode);     if (statusCode != HttpStatus.SC_OK) {      throw AppException.http(statusCode);     }       InputStream is = response.getEntity().getContent();       Header contentEncoding = response       .getFirstHeader("Content-Encoding");     if (contentEncoding != null       && contentEncoding.getValue().equalsIgnoreCase("gzip")) {      is = new GZIPInputStream(new BufferedInputStream(is));     }     return is;      } catch (ClientProtocolException e) {     e.printStackTrace();     throw AppException.http(e);    } catch (IOException e) {     e.printStackTrace();     throw AppException.network(e);    } finally {       /*      * if (!post.isAborted()) {      *       * post.abort(); } httpclient = null;      */      }     }

来自:http://blog.csdn.net/shimiso/article/details/9033117