JBoss/tomcat---gzip

 

 

开发了一个Web项目,在IE7和Firefox下测试全部ok,但在Ie6下发现个别画面出现假死机现象,写了一大堆js代码跟踪,发现在js中动态load js文件时,严重超时。而这个现象在tomcat不发生只在jboss中发生。比较tomcat和jboss的配置,发现唯一不同在于jboss启用了gzip 

Java代码     收藏代码
  1. <Connector port= "80"  address= "0.0.0.0"       
  2.         maxThreads="250"  maxHttpHeaderSize= "8192"   
  3.         emptySessionPath="true"  protocol= "HTTP/1.1"   
  4.         enableLookups="false"  redirectPort= "8443"  acceptCount= "100"   
  5.         connectionTimeout="20000"  disableUploadTimeout= "true"    
  6.        compression="on"       
  7.        compressionMinSize="1536"       
  8.            noCompressionUserAgents="gozilla, traviata"       
  9.            compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,application/json"   /> 





从上面的 第8行 内容可以看出,要使用gzip压缩功能,你可以在Connector实例中加上如下属性即可
1) compression="on" 打开压缩功能
2) compressionMinSize="2048" 启用压缩的输出内容大小,这里面默认为2KB
3) noCompressionUserAgents="gozilla, traviata" 对于以下的浏览器,不启用压缩 
4) compressableMimeType="text/html,text/xml" 压缩类型

 

 

 

 






下面是tomcat5.5.20 中的$tomcat_home$/conf/server.xml的原内容

 1          <   Connector    port   ="80"    maxHttpHeaderSize   ="8192"  
 2                 maxThreads   ="150"    minSpareThreads   ="25"    maxSpareThreads   ="75"  
 3                 enableLookups   ="false"    redirectPort   ="8443"    acceptCount   ="100"  
 4                  connectionTimeout   ="20000"    disableUploadTimeout   ="true"    URIEncoding   ="utf-8"       />  
 5         <!--    Note : To disable connection timeouts, set connectionTimeout value
 6       to 0    -->  
 7       
 8         <!--    Note : To use gzip compression you could set the following properties :
 9       
10                  compression="on" 
11                  compressionMinSize="2048" 
12                  noCompressionUserAgents="gozilla, traviata" 
13                  compressableMimeType="text/html,text/xml"
14          -->



 

 

 

 

 

 

 

 

二、  通过程序实现

采用 gzip servlet filter 实现

  HTTP/1.1  开始,客户端就可以在请求头中添加

Accept-Encoding: gzip,deflate      (可以从 HTTP WATCH 中查看发现确实支持)

来向请求的服务器表明自己支持   Gzip  压缩的响应。 Web  服务器则在响应头中添加

Content-Encoding: gzip
来向客户端表明响应体是经过
 gzip 
压缩的。

 

程序代码如下:

(在此非常感谢   提供代码)

具体代码如下:

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 输出提高下载的速度!

 

 

 

 

 


 

 

 


你可能感兴趣的:(tomcat,算法,jboss,浏览器,null,compression)