gzip压缩

来源:互联网 发布:linux 发送广播包命令 编辑:程序博客网 时间:2024/05/02 13:49

在web.xml中的配置:

<filter>
        
<filter-name>compressionFilter</filter-name>
        
<filter-class>org.xblogx.base.GZIPFilter</filter-class>
</filter>
<filter-mapping>
        
<filter-name>compressionFilter</filter-name>
        
<url-pattern>*.jsp</url-pattern>
</filter-mapping>     

类GZIPFilter
package org.xblogx.base;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.displaytag.tags.TableTagParameters;
import org.springframework.web.filter.OncePerRequestFilter;


public class GZIPFilter extends OncePerRequestFilter {
    
private final transient Log log = LogFactory.getLog(GZIPFilter.class);

    
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, 
                                 FilterChain chain)
    
throws IOException, ServletException {

        
if (isGZIPSupported(request)) {
            
if (log.isDebugEnabled()) {
                log.debug(
"GZIP supported, compressing response");
            }


            GZIPResponseWrapper wrappedResponse 
=
                
new GZIPResponseWrapper(response);

            chain.doFilter(request, wrappedResponse);
            wrappedResponse.finishResponse();

            
return;
        }


        chain.doFilter(request, response);
    }


    
/**
     * Convenience method to test for GZIP cababilities
     * 
@param req The current user request
     * 
@return boolean indicating GZIP support
     
*/

    
private boolean isGZIPSupported(HttpServletRequest req) {
        
        
// disable gzip filter for exporting from displaytag
        String exporting = req.getParameter(TableTagParameters.PARAMETER_EXPORTING);
        
        
if (exporting != null{
            log.debug(
"detected excel export, disabling filter...");
            
return false;
        }


        String browserEncodings 
= req.getHeader("accept-encoding");
        
boolean supported = ((browserEncodings != null&&
                             (browserEncodings.indexOf(
"gzip"!= -1));

        String userAgent 
= req.getHeader("user-agent");

        
if ((userAgent != null&& userAgent.startsWith("httpunit")) {
            log.debug(
"httpunit detected, disabling filter...");

            
return false;
        }
 else {
            
return supported;
        }

    }

}

 类GZIPResponseStream:

package org.xblogx.base;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;


/**
 * Wraps Response Stream for GZipFilter
 *
 * 
@author  Matt Raible
 * 
@version $Revision: 1.3 $ $Date: 2004-05-15 20:18:10 -0600 (Sat, 15 May 2004) $
 
*/

public class GZIPResponseStream extends ServletOutputStream {
    
// abstraction of the output stream used for compression
    protected OutputStream bufferedOutput = null;

    
// state keeping variable for if close() has been called
    protected boolean closed = false;

    
// reference to original response
    protected HttpServletResponse response = null;

    
// reference to the output stream to the client's browser
    protected ServletOutputStream output = null;

    
// default size of the in-memory buffer
    private int bufferSize = 50000;

    
public GZIPResponseStream(HttpServletResponse response)
    
throws IOException {
        
super();
        closed 
= false;
        
this.response = response;
        
this.output = response.getOutputStream();
        bufferedOutput 
= new ByteArrayOutputStream();
    }


    
public void close() throws IOException {
        
// verify the stream is yet to be closed
        if (closed) {
            
throw new IOException("This output stream has already been closed");
        }


        
// if we buffered everything in memory, gzip it
        if (bufferedOutput instanceof ByteArrayOutputStream) {
            
// get the content
            ByteArrayOutputStream baos = (ByteArrayOutputStream) bufferedOutput;

            
// prepare a gzip stream
            ByteArrayOutputStream compressedContent =
                
new ByteArrayOutputStream();
            GZIPOutputStream gzipstream 
=
                
new GZIPOutputStream(compressedContent);
            
byte[] bytes = baos.toByteArray();
            gzipstream.write(bytes);
            gzipstream.finish();

            
// get the compressed content
            byte[] compressedBytes = compressedContent.toByteArray();

            
// set appropriate HTTP headers
            response.setContentLength(compressedBytes.length);
            response.addHeader(
"Content-Encoding""gzip");
            output.write(compressedBytes);
            output.flush();
            output.close();
            closed 
= true;
        }

        
// if things were not buffered in memory, finish the GZIP stream and response
        else if (bufferedOutput instanceof GZIPOutputStream) {
            
// cast to appropriate type
            GZIPOutputStream gzipstream = (GZIPOutputStream) bufferedOutput;

            
// finish the compression
            gzipstream.finish();

            
// finish the response
            output.flush();
            output.close();
            closed 
= true;
        }

    }


    
public void flush() throws IOException {
        
if (closed) {
            
throw new IOException("Cannot flush a closed output stream");
        }


        bufferedOutput.flush();
    }


    
public void write(int b) throws IOException {
        
if (closed) {
            
throw new IOException("Cannot write to a closed output stream");
        }


        
// make sure we aren't over the buffer's limit
        checkBufferSize(1);

        
// write the byte to the temporary output
        bufferedOutput.write((byte) b);
    }


    
private void checkBufferSize(int length) throws IOException {
        
// check if we are buffering too large of a file
        if (bufferedOutput instanceof ByteArrayOutputStream) {
            ByteArrayOutputStream baos 
= (ByteArrayOutputStream) bufferedOutput;

            
if ((baos.size() + length) > bufferSize) {
                
// files too large to keep in memory are sent to the client without Content-Length specified
                response.addHeader("Content-Encoding""gzip");

                
// get existing bytes
                byte[] bytes = baos.toByteArray();

                
// make new gzip stream using the response output stream
                GZIPOutputStream gzipstream = new GZIPOutputStream(output);
                gzipstream.write(bytes);

                
// we are no longer buffering, send content via gzipstream
                bufferedOutput = gzipstream;
            }

        }

    }


    
public void write(byte[] b) throws IOException {
        write(b, 
0, b.length);
    }


    
public void write(byte[] b, int off, int len) throws IOException {

        
if (closed) {
            
throw new IOException("Cannot write to a closed output stream");
        }


        
// make sure we aren't over the buffer's limit
        checkBufferSize(len);

        
// write the content to the buffer
        bufferedOutput.write(b, off, len);
    }


    
public boolean closed() {
        
return (this.closed);
    }


    
public void reset() {
        
//noop
    }

}

类GZIPResponseWrapper:
package org.xblogx.base;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * Wraps Response for GZipFilter
 *
 * 
@author  Matt Raible, cmurphy@intechtual.com
 
*/

public class GZIPResponseWrapper extends HttpServletResponseWrapper {
    
private transient final Log log = LogFactory.getLog(GZIPResponseWrapper.class);
    
protected HttpServletResponse origResponse = null;
    
protected ServletOutputStream stream = null;
    
protected PrintWriter writer = null;
    
protected int error = 0;

    
public GZIPResponseWrapper(HttpServletResponse response) {
        
super(response);
        origResponse 
= response;
    }


    
public ServletOutputStream createOutputStream() throws IOException {
        
return (new GZIPResponseStream(origResponse));
    }


    
public void finishResponse() {
        
try {
            
if (writer != null{
                writer.close();
            }
 else {
                
if (stream != null{
                    stream.close();
                }

            }

        }
 catch (IOException e) {
        }

    }


    
public void flushBuffer() throws IOException {
        
if (stream != null{
            stream.flush();
        }

    }


    
public ServletOutputStream getOutputStream() throws IOException {
        
if (writer != null{
            
throw new IllegalStateException("getWriter() has already been called!");
        }


        
if (stream == null{
            stream 
= createOutputStream();
        }


        
return (stream);
    }


    
public PrintWriter getWriter() throws IOException {
        
// From cmurphy@intechtual.com to fix:
        
// https://appfuse.dev.java.net/issues/show_bug.cgi?id=59
        if (this.origResponse != null && this.origResponse.isCommitted()) {
            
return super.getWriter();
        }


        
if (writer != null{
            
return (writer);
        }


        
if (stream != null{
            
throw new IllegalStateException("getOutputStream() has already been called!");
        }


        stream 
= createOutputStream();
        writer 
=
            
new PrintWriter(new OutputStreamWriter(stream,
                                                   origResponse.getCharacterEncoding()));

        
return (writer);
    }


    
public void setContentLength(int length) {
    }


    
/**
     * 
@see javax.servlet.http.HttpServletResponse#sendError(int, java.lang.String)
     
*/

    
public void sendError(int error, String message) throws IOException {
        
super.sendError(error, message);
        
this.error = error;

        
if (log.isDebugEnabled()) {
            log.debug(
"sending error: " + error + " [" + message + "]");
        }

    }

}

原创粉丝点击