HTTP 實現GZip/Deflate數據傳輸壓縮

數據壓縮式在B/S客戶端中常見的一種數據傳輸方式,這種方式主要做用是用來將大量壓縮效果好數據和文件進行壓縮傳輸。java

注:壓縮效果好主要指,壓縮後數據體積明細變小,壓縮時耗費內存較少,因此,並非全部的大型數據都應該壓縮的,好比exe,apk,ipa等文件。ajax


首先,創建一個Model跨域

public class User implements Serializable
{
    private long uid;
    
    private String name;
    
    private String password;
    
    public User(){}
    
    public User(long uid,String name,String password){
        this.uid = uid;
        this.name = name;
        this.password = password;
    }
    
    /**setter,getter請自行補充**/
}

服務端瀏覽器

(這裏使用Servlet,PHP也能夠,關於PHP的gzip配置和使用,請參考http://www.jb51.net/article/38217.htmhttp://www.jb51.net/article/60601.htm安全

/**
* 判斷瀏覽器是否支持 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;  
}  


public void doPost(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {  
   response.setCharacterEncoding("utf-8");  
   response.setHeader("Content-Encoding", "gzip");  
   response.setHeader("Access-Control-Allow-Origin", "*");//支持ajax跨域
    
    if("admin".equal(request.getParameter("name")) && "admin".equal(request.getParameter("password")))
    {

    List<User> userList = new ArrayList<User>();
    userList.add(new User(1024,"Zhangsan","ZhangsanPwd"));
    userList.add(new User(1025,"username","password"));
    userList.add(new User(1026,"lisi","lisi123"));
    userList.add(new User(1027,"wangwu","wangwu"));
    userList.add(new User(1028,"oschina","oschina"));
   
   PrintWriter pw = createGzipPw(request,response);  
   pw.write(new Gson().toJson(userList,new TypeToken<List<User>(){}.getType()));  
   pw.close();  
   
   }
}  
 
public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {  
   this.doPost(request, response);  
}

固然,服務器端沒問題了,下一步就是客戶端了服務器

Android 客戶端app

HttpClient httpClient =  new DefaultHttpClient();

 HttpPost httpPost = new HttpPost("http://192.168.1.106/app/GateWay/GzipServlet");
 httpPost.addHeader("Referer", "http://my.oschina.net/ososchina");
 httpPost.addHeader("X-Requested-With", "XMLHttpRequest");//此處支持ajax請求,這裏沒太多意義
 httpPost.addHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
 httpPost.addHeader("Accept", "*/*");
 httpPost.addHeader("Accept-Encoding", "gzip, deflate"); //聲明給服務器,客戶端支持gzip解壓
 httpPost.addHeader("Accept-Language", "zh-cn,en-us;q=0.7,en;q=0.3");
 httpPost.addHeader("Pragma", "no-cache");
 httpPost.addHeader("Cache-Control", "no-cache");
 
 List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
 params.add(new BasicNameValuePair("name","admin"));
 params.add(new BasicNameValuePair("password", "admin"));

 
  UrlEncodedFormEntity formEntity = null;
  HttpResponse response = null;
  String responseHtml = null;
  try{
         formEntity = new UrlEncodedFormEntity(params, "utf-8");
         httpPost.setEntity(formEntity);
         response = httpClient.execute(post);
         InputStream is= null;
          if ("gzip".equalsIgnoreCase(response.getEntity().getContentEncoding().getValue())) { 
                    httpEntity = new GzipDecompressingEntity(httpEntity); 
           } else if ("deflate".equalsIgnoreCase(response.getEntity().getContentEncoding().getValue())) { 
                  httpEntity = new DeflateDecompressingEntity(httpEntity);                    
            }
          
          is= new GZIPInputStream( response.getEntity().getContent());
          BufferedReader br = new BufferedReader(new InputStreamReader(is));
          String line = null;
          StringBuffer sb = new StringBuffer();
            while((line = br.readLine())!=null) {
             sb.append(line);
            }
            responseHtml = sb.toString(); //讀取解壓數據,固然,你也能夠將其保存成文件
            is.close();
        } catch (Exception e)
        {
           e.printStackTrace();
        }


在開發Android時,數據量並不大,不管是請求或者響應,所以gzip用途就沒有B/S模型普遍,但gzip仍是有用武之地的,主要用於以「 加密+gzip壓縮"的方式進行數據的安全傳輸。post


Java原聲的API提供了GZIPInputStream和DeflaterInputStreamui

相關文章
相關標籤/搜索