gzip压缩

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gzip压缩相关的知识,希望对你有一定的参考价值。

有端和服务器的数据传输量太大,导致网络传输慢问题,有以下方案,一个是让tomcat去做数据的压缩,另外一个是使用gzip对参数压缩。


一,tomcat加上gzip压缩配置

    配置:在tomcat的server.xml中配置以下信息

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"  

                 compression="on"   //是否启动压缩

               compressionMinSize1="2048"  //最小开始压缩的大小
               noCompressionUserAgents="gozilla, traviata"  //不压缩的浏览器
               compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,application/json,text/json" //content-type类型设定

       />

    性能:没有加此配置项119M的json数据,print到浏览器上耗时1.4min左右,加上配置项之后50s左右,减小40%左右。


二,数据传输参数压缩


    源字符串:892MB

    压缩后字符串:3MB
    解压前字符串:3MB
    解压后字符串:892MB
    压缩耗时:8631ms,解压耗时:4354ms

    

package com.try2better.daily.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.try2better.daily.util.gzip.GzipUtils;


@Controller
@RequestMapping("/gzip")
public class GZipController {
	
    @ResponseBody
    @RequestMapping(value = "/get")
    public JSONArray get() throws Exception {
        return GzipUtils.getTestData();
    }
    
    @ResponseBody
    @RequestMapping(value = "/fetch",method = RequestMethod.POST)
    public byte[] fetch(){
        return GzipUtils.gzip(GzipUtils.getTestData().toJSONString());
    }
    
    @ResponseBody
    @RequestMapping(value = "/receive",method = RequestMethod.POST)
    public String receive(@RequestBody byte[] byt){
    	String sss =  GzipUtils.ungzip(byt);
    	System.out.println(sss);
    	return sss;
    }

    @ResponseBody
    @RequestMapping(value = "/set1")
    public int set1(@RequestBody String jsonString){
        JSONArray jsonArray = JSONArray.parseArray(jsonString);
        System.out.println(jsonArray.size());
        return jsonArray.size();
    }

    @ResponseBody
    @RequestMapping(value = "/set2")
    public int set2(@RequestBody JSONArray jsonArray){
    	System.out.println(jsonArray.size());
       return jsonArray.size();
    }



}


    

package com.try2better.daily.util.gzip;


public class Main {
	
	public static void main(String[] args) throws Exception {
		//get
		byte[] dd = GzipHttpUtil.getInstance().sendHttpPost("http://127.0.0.1:8888/gzip/fetch");
		String dddd = GzipUtils.ungzip(dd);
		System.out.println(dddd);
		
		//set
		byte[] sss = GzipUtils.gzip(dddd);
		GzipHttpUtil.getInstance().sendHttpPostByteArrayResult("http://127.0.0.1:8888/gzip/receive", sss);
	}
}



    

package com.try2better.daily.util.gzip;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
public class GzipHttpUtil {  
	
	private static final Integer TIMEOUT = 15000;
	private static final String ENCODE = "UTF-8";
       
    private static GzipHttpUtil instance = null; 
    private RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(TIMEOUT).setConnectTimeout(TIMEOUT).setConnectionRequestTimeout(TIMEOUT).build();
    
    private GzipHttpUtil(){
    	
    }   
    
    public static GzipHttpUtil getInstance(){    
    	if (instance == null) {    
    		instance = new GzipHttpUtil();    
        }    
        return instance;    
    }    
    
	/**  
	 * 发送 post请求  
	 * @param httpUrl 地址  
	 */    
	public byte[] sendHttpPost(String httpUrl) {    
	    HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost   
	    return sendHttpPostByteArrayResult(httpPost);    
	}    
            
	/**  
	 * 发送 post请求  
	 * @param httpUrl 地址  
	 * @param params 
	 */    
	public byte[] sendHttpPostByteArrayResult(String httpUrl, byte[] params) {    
	    HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost      
	    try {    
	    	//设置参数    
	        ByteArrayEntity arrayEntity = new ByteArrayEntity(params);  
	        httpPost.setEntity(arrayEntity);  
	    } catch (Exception e) {    
	        e.printStackTrace();    
	    }    
	    return sendHttpPostByteArrayResult(httpPost);    
	}        
	
	public String sendHttpPostStringResult(String httpUrl, byte[] params) {  
		byte[] bytes = sendHttpPostByteArrayResult(httpUrl,params);
		if(bytes != null){
			try {
				return new String(bytes,ENCODE);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
	    return null;        
	}  
	
	/**  
	 * 发送 post请求  
	 * @param httpUrl 地址  
	 * @param maps 参数  
	 */    
	public byte[] sendHttpPost(String httpUrl, Map<String,String> maps) {    
	    HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost     
		// 创建参数队列      
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();    
		for (String key : maps.keySet()) {    
		    nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));    
		}    
		try {    
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, ENCODE));    
	    } catch (Exception e) {    
	        e.printStackTrace();    
	    }    
	    return sendHttpPostByteArrayResult(httpPost);    
	}          
	/**  
	 * 发送Post请求  
	 * @param httpPost  
	 * @return  
	 */    
	private byte[] sendHttpPostByteArrayResult(HttpPost httpPost) {    
		CloseableHttpClient httpClient = null;    
	    CloseableHttpResponse response = null;    
	    HttpEntity entity = null;    
	    byte[] responseContent = null;    
	    try {    
	        // 创建默认的httpClient实例.    
			httpClient = HttpClients.createDefault();    
			httpPost.setConfig(requestConfig);   
			// 执行请求    
			response = httpClient.execute(httpPost);    
			entity = response.getEntity();   
			responseContent = EntityUtils.toByteArray(entity);  
	    } catch (Exception e) {    
	    	e.printStackTrace();    
	    } finally {    
	    	try {    
	    		// 关闭连接,释放资源    
	            if (response != null) {    
	                response.close();    
	            }    
	            if (httpClient != null) {    
	                httpClient.close();    
	            }    
	        } catch (IOException e) {    
	            e.printStackTrace();    
	        }    
	    }    
	    return responseContent;    
	}    
}


    

package com.try2better.daily.util.gzip;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

public class GzipUtils {
	
	private static final String ENCODE = "UTF-8";
	
	public static byte[] gzip(String str) {  
		if(str == null){
			return null;
		}
		GZIPOutputStream gzip = null;
		ByteArrayOutputStream bos = null;
		try {
			byte[] data = str.getBytes(ENCODE);
			System.out.println("源字符串:" + data.length / 1024 /1024 + "MB");
		    bos = new ByteArrayOutputStream();  
	        gzip = new GZIPOutputStream(bos);  
	        gzip.write(data);  
	        gzip.finish();  
	        byte[] ret = bos.toByteArray(); 
	        System.out.println("压缩后字符串:" + ret.length / 1024 /1024 + "MB");
	        return ret;  
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			try {
				if(gzip != null){
					gzip.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}  
			try {
				if(bos != null){
					bos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}  
		}
		return null;
    }  
	  
    public static String ungzip(byte[] data) { 
    	if(data == null || data.length == 0){
    		return null;
    	}
    	GZIPInputStream gzip = null;
    	ByteArrayOutputStream bos = null;
    	ByteArrayInputStream bis = null;
    	try {
    		System.out.println("解压前字符串:" + data.length / 1024 /1024 + "MB");
            bis = new ByteArrayInputStream(data);  
            gzip = new GZIPInputStream(bis);  
            byte[] buf = new byte[1024];  
            int num = -1;  
            bos = new ByteArrayOutputStream();  
            while ((num = gzip.read(buf, 0, buf.length)) != -1) {  
                bos.write(buf, 0, num);  
            }  
            
            byte[] ret = bos.toByteArray(); 
            System.out.println("解压后字符串:" + ret.length / 1024 /1024 + "MB");
            bos.flush();  
            
            return new String(ret,ENCODE);  
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			try {
				if(gzip != null){
					gzip.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}  
            try {
            	if(bis != null){
            		bis.close();
            	}
			} catch (IOException e) {
				e.printStackTrace();
			}  
            try {
            	if(bos != null){
            		bos.close();
            	}
			} catch (IOException e) {
				e.printStackTrace();
			}  
		}
    	return null;
    }  
	    
    public static JSONArray getTestData(){
        JSONArray jsonArray = new JSONArray();
        for (int i = 0; i < 3; i++) {
            JSONObject json = new JSONObject();
            json.put("id",i);
            json.put("username","周晖" + i);
            json.put("sex","m");
            json.put("content","这曾是他最熟悉的,而今,已是他最陌生的。32岁的亨利就坐在那里,深情的目光望过去,都是自己22岁的影子。380场比赛,226个进球,4座英超金靴,2座英超奖杯,49场不败。"
            		+ "历史最佳射手,海布里的最后一战,海布里的最后一吻。当烟花升起的时刻,那个曾属于亨利的海布里国王时代不会随年华逝去,而只会在年华的飘零中常常记起。");
            jsonArray.add(json);
        }
        return jsonArray;
    }
	    
    public static void main(String[] args) throws Exception {  
    	String sss = getTestData().toJSONString();
    	byte[] b = gzip(sss);
    	System.out.println(ungzip(b));
	}  
}


以上是关于gzip压缩的主要内容,如果未能解决你的问题,请参考以下文章

开启Nginx的gzip压缩功能详解

使用Gzip压缩数据,加快页面访问速度

Gzip压缩优化网站

Tomcat7中开启gzip压缩功能的配置方法

nginx/express 开启gzip压缩

缓存 gzip 压缩的 css