1. 程式人生 > >tomcat配置gzip壓縮注意事項

tomcat配置gzip壓縮注意事項

設定tomcat啟用GZIP壓縮注意事項

原理簡介

HTTP 壓縮可以大大提高瀏覽網站的速度,它的原理是,在客戶端請求伺服器對應資源後,從伺服器端將資原始檔壓縮,再輸出到客戶端,由客戶端的瀏覽器負責解壓縮並瀏覽。相對於普通的瀏覽過程HTML ,CSS,Javascript , Text ,它可以節省40%左右的流量。更為重要的是,它可以對動態生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等輸出的網頁也能進行壓縮,壓縮效率也很高。 

配置方法

Tomcat5.0以後的版本是支援對輸出內容進行壓縮的,使用的是gzip壓縮格式 。 修改%TOMCAT_HOME%/conf/server.xml,修訂節點如下:
      
  1. <Connectorport="80"protocol="HTTP/1.1"
  2.            connectionTimeout="20000"
  3.            redirectPort="8443"executor="tomcatThreadPool"URIEncoding="utf-8"
  4.                        compression="on"
  5.                        compressionMinSize="50"noCompressionUserAgents="gozilla, traviata"
  6.                        compressableMimeType
    ="text/html,text/xml,text/javascript,text/css,text/plain"/>
 
  • compression="on" 開啟壓縮功能 
  • compressionMinSize="50" 啟用壓縮的輸出內容大小,預設為2KB 
  • noCompressionUserAgents="gozilla, traviata" 對於以下的瀏覽器,不啟用壓縮 
  • compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 哪些資源型別需要壓縮

測試方法

1.通過瀏覽器訪問抓包看是否有gzip欄位,資料量是否減少(firebug

2.通過httpclient程式模擬

package com.annotation.test;

import org.apache.commons.httpclient.HttpClient;

import org.apache.commons.httpclient.HttpStatus;

public class TestGzip {

	private final static String url = "http://192.168.14.216/demo/test2";

	public static void main(String[] args) throws Exception {

		HttpClient http = new HttpClient();

		CustomGetMethod get = new CustomGetMethod(url);

		// 新增頭資訊告訴服務端可以對Response進行GZip壓縮
		get.setRequestHeader("Accept-Encoding", "gzip,deflate");
		get.setRequestHeader("Header","{\"version\":\"1.0.0\",\"clienttype\":\"3\"}");
		get.setRequestHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
		try {
			int statusCode = http.executeMethod(get);

			if (statusCode != HttpStatus.SC_OK) {

				System.err.println("Method failed: "

				+ get.getStatusLine());

			}
			// 列印解壓後的返回資訊
			String after  = get.getResponseBodyAsString();
			System.out.println(after+"|size="+after.getBytes().length);

		} catch (Exception e) {

			System.err.println("頁面無法訪問");

			e.printStackTrace();

		} finally {

			get.releaseConnection();

		}
	}
}

package com.annotation.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.methods.GetMethod;
public class CustomGetMethod extends GetMethod {
	public CustomGetMethod(String uri) {
		super(uri);
	}
	public String getResponseBodyAsString() throws IOException {
		GZIPInputStream gzin;
		String before = super.getResponseBodyAsString();
		System.out.println(before+"|size="+before.getBytes().length);	
		Header[] headers = getResponseHeaders();
		for(Header header:headers){
			System.out.println(header.getName()+"|"+header.getValue());
		}
		if (getResponseBody() != null || getResponseStream() != null) {
			if (getResponseHeader("Content-Encoding") != null&& getResponseHeader("Content-Encoding").getValue().toLowerCase().indexOf("gzip") > -1) {
				// For GZip response
				InputStream is = getResponseBodyAsStream();
				gzin = new GZIPInputStream(is);
				InputStreamReader isr = new InputStreamReader(gzin);
				java.io.BufferedReader br = new java.io.BufferedReader(isr);
				StringBuffer sb = new StringBuffer();
				String tempbf;
				while ((tempbf = br.readLine()) != null) {
					sb.append(tempbf);
					sb.append("\r\n");
				}
				isr.close();
				gzin.close();
				return sb.toString();
			} else {
				// For deflate response
				return super.getResponseBodyAsString();
			}
		} else {
			return null;
		}
	}
}


注意事項

1. 客戶端的http頭裡面要帶上getMethod.setRequestHeader("Accept-Encoding","gzip, deflate"); 表示客戶端支援gzip壓縮,如果返回的response頭裡面有Content-Encoding並且value=”gzip”,則表示需要用gzip解壓。
2. 注意客戶端傳遞的request頭裡面,必須帶有accept頭,表示支援text格式get.setRequestHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"),否則可能伺服器會預設返回application/octet-stream格式的報文,結果server.xml檔案沒配置這種格式的壓縮,伺服器不會壓縮。

3. “If the content-length is not known and compression is set to "on" or more aggressive, the output will also be compressed. If not specified, this attribute is set to "off"" (點選開啟連結)引用tomcat7.0官方文件的話,當返回報文content-length未知,又開啟了壓縮,則不管報文大小都會忽略最小壓縮長度,直接進行壓縮。