HTTP 壓縮能夠大大提升瀏覽網站的速度,它的原理是,在客戶端請求網頁後,從服務器端將網頁文件壓縮,再下載到客戶端,由客戶端的瀏覽器負責解壓縮並瀏覽。相對 於普通的瀏覽過程HTML ,CSS,Javascript , Text ,它能夠節省40%左右的流量。更爲重要的是,它能夠對動態生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等輸出的網頁也能進行壓縮,壓縮效率驚人。
目前實現gzip壓縮有2種辦法:
方法1、是有的容器(服務器)提供的功能,但這個侷限於特定容器。好比
apache+tomcat
或者
resin-pro
版
。
方法2、是 部署前手動
gzip
壓縮,配合
servlet
過濾器使用,這個能實現
gzip
功能,可是下降了靈活性。
方案一
一、TOMCAT配置GZIP壓縮:
tomcat5.5.x配置
修改%TOMCAT_HOME%\conf \server.xml啓用支持gzip壓縮.
添加下列屬性
compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml"
TOMCAT配置說明
1) compression="on" 打開壓縮功能
2) compressionMinSize="2048" 啓用壓縮的輸出內容大小,這裏面默認爲2KB
3) noCompressionUserAgents="gozilla, traviata" 對於如下的瀏覽器,不啓用壓縮
4) compressableMimeType="text/html,text/xml" 壓縮類型
Resin容器中配置GZIP壓縮方法
http://localhost:8080/MyProj/pdf/0.jpg 能夠打開一張圖片。用Httpwatch查看
Accept-Encoding: gzip, deflate
Sent : 315
Received 43106
開始配置Resin
我按照這樣的配置:
<web-app id="/" root-directory="webapps/MyProj">
<filter filter-name="gzip" filter-class="com.caucho.filters.GzipFilter">
<init>
<use-vary>true</use-vary>
</init>
</filter>
<filter-mapping filter-name="gzip">
<url-pattern>
<exclude-pattern>*.jpg</exclude-pattern>
<include-pattern>/*</include-pattern>
</url-pattern>
</filter-mapping>
</web-app>
再測試發現不起做用!不清楚如何配置哦!
我再看了一下資料上面有講說 須要resin的專業版即resin-pro
如今再看下個人resin :Resin-3.2.1 (built Fri, 17 Oct 2008 04:11:01 PDT)
果真是個人版本不一致致使的。從新從網上下載一下專業版的RESIN下來再試!
如下是我再測試的過程:
測試發現仍是不行呀!我昏~~~ 不過感受專業版與普通版在配置上面仍是有點差異的
待續未完!
方案二:
設置Content-Encoding
Content-Encoding 文檔的編碼(Encode)方法。只有在解碼以後才能夠獲得Content-Type頭指定的內容類型。利用gzip壓縮文檔可以顯著地減小HTML文檔 的下載時間。Java的GZIPOutputStream能夠很方便地進行gzip壓縮,但只有Unix上的Netscape和Windows上的IE 四、IE 5才支持它。所以,Servlet應該經過查看Accept-Encoding頭(即request.getHeader("Accept- Encoding"))檢查瀏覽器是否支持gzip,爲支持gzip的瀏覽器返回經gzip壓縮的HTML頁面,爲其餘瀏覽器返回普通頁面。
壓縮流
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
OutputStream out = null;
String encoding = request.getHeader("Accept-Encoding");
if (encoding != null && encoding.indexOf("gzip") != -1){
request.setHeader("Content-Encoding" , "gzip");
out = new GZIPOutputStream(request.getOutputStream());
}
else if (encoding != null && encoding.indexOf("comdivss") != -1){
request.setHeader("Content-Encoding" , "comdivss");
out = new ZIPOutputStream(request.getOutputStream());
}else{
out = request.getOutputStream();
實例:
採用gzip servlet filter實現
從 HTTP/1.1 開始,客戶端就能夠在請求頭中添加
Accept-Encoding: gzip,deflate (能夠從HTTP WATCH中查看發現確實支持)
來向請求的服務器代表本身支持 Gzip 壓縮的響應。Web 服務器則在響應頭中添加
Content-Encoding: gzip
來向客戶端代表響應體是通過 gzip 壓縮的。
程序代碼以下:
(在此很是感謝 http://tdcq.iteye.com/blog/453644 提供代碼)
具體代碼以下:
package sh.blog.util.web.filter;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
public class CompressedStream extends ServletOutputStream {
private ServletOutputStream out;
private GZIPOutputStream gzip;
/**
* 指定壓縮緩衝流
* @param 輸出流到壓縮
* @throws IOException if an error occurs with the {@link GZIPOutputStream}.
*/
public CompressedStream(ServletOutputStream out) throws IOException {
this.out = out;
reset();
}
/** @see ServletOutputStream * */
public void close() throws IOException {
gzip.close();
}
/** @see ServletOutputStream * */
public void flush() throws IOException {
gzip.flush();
}
/** @see ServletOutputStream * */
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
/** @see ServletOutputStream * */
public void write(byte[] b, int off, int len) throws IOException {
gzip.write(b, off, len);
}
/** @see ServletOutputStream * */
public void write(int b) throws IOException {
gzip.write(b);
}
public void reset() throws IOException {
gzip = new GZIPOutputStream(out);
}
}
package sh.blog.util.web.filter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class CompressionResponse extends HttpServletResponseWrapper{
protected HttpServletResponse response;
private ServletOutputStream out;
private CompressedStream compressedOut;
private PrintWriter writer;
protected int contentLength;
public CompressionResponse(HttpServletResponse response) throws IOException {
super(response);
this.response = response;
compressedOut = new CompressedStream(response.getOutputStream());
}
public void setContentLength(int len) {
contentLength = len;
}
public ServletOutputStream getOutputStream() throws IOException {
if (null == out) {
if (null != writer) {
throw new IllegalStateException("getWriter() has already been called on this response.");
}
out = compressedOut;
}
return out;
}
public PrintWriter getWriter() throws IOException {
if (null == writer) {
if (null != out) {
throw new IllegalStateException("getOutputStream() has already been called on this response.");
}
writer = new PrintWriter(compressedOut);
}
return writer;
}
public void flushBuffer() {
try {
if (writer != null) {
writer.flush();
}else if (out != null) {
out.flush();
}
}catch (IOException e) {
e.printStackTrace();
}
}
public void reset() {
super.reset();
try {
compressedOut.reset();
}catch (IOException e) {
throw new RuntimeException(e);
}
}
public void resetBuffer() {
super.resetBuffer();
try {
compressedOut.reset();
}catch (IOException e) {
throw new RuntimeException(e);
}
}
public void close() throws IOException {
compressedOut.close();
}
}
package sh.blog.util.web.filter;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class CompressionFilter implements Filter {
protected Log log = LogFactory.getFactory().getInstance(this.getClass().getName());
@SuppressWarnings("unchecked")
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
boolean compress = false;
if (request instanceof HttpServletRequest){
HttpServletRequest httpRequest = (HttpServletRequest) request;
Enumeration headers = httpRequest.getHeaders("Accept-Encoding");
while (headers.hasMoreElements()){
String value = (String) headers.nextElement();
if (value.indexOf("gzip") != -1){
compress = true;
}
}
}
if (compress){//若是瀏覽器支持則壓縮
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.addHeader("Content-Encoding", "gzip");
CompressionResponse compressionResponse= new CompressionResponse(httpResponse);
chain.doFilter(request, compressionResponse);
compressionResponse.close();
}
else{//若是瀏覽器不支持則不壓縮
chain.doFilter(request, response);
}
}
public void init(FilterConfig config) throws ServletException {
}
public void destroy(){
}
}
一共有三個CLASS文件!實現GZIP壓縮輸出響應
2.1 對圖片輸出作壓縮處理測試
創建目錄pdf裏面存儲圖片
第一步:不配置過濾器用HTTP WATCHE發現
image/jpeg : 42891 bytes, 670 x 446 pixels
第二步:配置Web.xml配置過濾器
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/pdf/*</url-pattern>
</filter-mapping>
再用HTTP WATCH查看發現
image/jpeg : 42891 bytes, gzip compressed to 42712 bytes ( 0.417 % saving ), 670 x 446 pixels
實現了一次壓縮處理輸出!
PS:我再用png格式的圖片作過一次測試發現一次能夠實現GZIP壓縮輸出
結論:經過上面的過濾器可以實現對圖片的壓縮處理,提升響應速度!
2.2 對音樂的壓縮處理以MP3的輸出 爲測試對象
創建目錄music裏面存儲音樂
第一步:不配置過濾器發現
audio/mpeg : 9001 bytes of binary data
第二步:配置過濾器
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/music/*</url-pattern>
</filter-mapping>
再次查看發現:
audio/mpeg : , gzip compressed to 0 bytes ( 0 % saving )
結論:上面的算法對音樂文件不起壓縮做用。感受這種GZIP的算法應該是不一樣的格式算法不同
2.3 對JS文件壓縮輸出
第一步:不作壓縮
4864
第二步:配置壓縮
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/scripts/*.js</url-pattern>
</filter-mapping>
輸出:
application/x-javascript : 4636 bytes, gzip compressed to 69 bytes ( 98.5 % saving )
查看發現JS的壓縮是至關高的了!
結論:將JS存入指定的目錄而後直接對此目錄作GZIP壓縮輸出。能夠看到效果是顯著的!
經過作GZIP壓縮輸出以後能夠減小網絡帶寬流量從而加快下載速度!
2.4 對CSS文件壓縮輸出
第一步:沒有壓縮輸出
text/css : 413 bytes
第二步:壓縮
配置:
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/scripts/*.js</url-pattern>
<url-pattern>/style/*.css</url-pattern>
</filter-mapping>
結果:
text/css : 413 bytes, gzip compressed to 101 bytes ( 75.5 % saving )
結論:對CSS的壓縮效果也是很是明顯的哦!
2.5 對HTML頁面壓縮輸出
第一步:不壓縮
text/html : 2272 bytes
第二步;壓縮
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/scripts/*.js</url-pattern>
<url-pattern>/style/*.css</url-pattern>
<url-pattern>*.html</url-pattern>
</filter-mapping>
結果:
text/html : 2272 bytes, gzip compressed to 240 bytes ( 89.4 % saving )
結論:對HTML的壓縮效果也是很是明顯的哦!
2.6 對JSP頁面的壓縮
第一步:未作壓縮
text/html; charset=iso-8859-1 : 1008 bytes
第二步:壓縮輸出
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/scripts/*.js</url-pattern>
<url-pattern>/style/*.css</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
結果:頁面 無輸出!
結論:
以上的算法能夠應用於 圖片、HTML、CSS、JS的GZIP壓縮輸出。對於JSP頁面無效!
應用:
未來能夠在站點中編寫此類過濾器,將頁面內容儘量地作GZIP輸出提升下載的速度 javascript
這是我在別處看到帖子 比較不錯 但願你們能夠看下
css