设置tomcat启用GZIP压缩注意事项
原理简介
HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求服务器对应资源后,从服务器端将资源文件压缩,再输出到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程HTML ,CSS,Javascript , Text ,它可以节省40%左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等输出的网页也能进行压缩,压缩效率也很高。
配置方法
Tomcat5.0以后的版本是支持对输出内容进行压缩的,使用的是gzip压缩格式 。
修改%TOMCAT_HOME%/conf/server.xml,修订节点如下:
- <Connector port="80" protocol="HTTP/1.1"
- connectionTimeout="20000"
- redirectPort="8443" executor="tomcatThreadPool" URIEncoding="utf-8"
- compression="on"
- compressionMinSize="50" noCompressionUserAgents="gozilla, traviata"
- 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未知,又开启了压缩,则不管报文大小都会忽略最小压缩长度,直接进行压缩。