数据压缩式在B/S客户端中常见的一种数据传输方式,这种方式主要作用是用来将大量压缩效果好数据和文件进行压缩传输。
注:压缩效果好主要指,压缩后数据体积明细变小,压缩时耗费内存较少,所以,并不是所有的大型数据都应该压缩的,比如exe,apk,ipa等文件。
首先,建立一个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.htm和http://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 客户端
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压缩"的方式进行数据的安全传输。
Java原声的API提供了GZIPInputStream和DeflaterInputStream