CompressionResponseStream.java
上传用户:bj_pst
上传日期:2019-07-07
资源大小:7353k
文件大小:9k
源码类别:

Java编程

开发平台:

Java

  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements.  See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License.  You may obtain a copy of the License at
  8. *
  9. *     http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package compressionFilters;
  18. import java.io.IOException;
  19. import java.io.OutputStream;
  20. import java.util.zip.GZIPOutputStream;
  21. import javax.servlet.ServletOutputStream;
  22. import javax.servlet.http.HttpServletResponse;
  23. /**
  24.  * Implementation of <b>ServletOutputStream</b> that works with
  25.  * the CompressionServletResponseWrapper implementation.
  26.  *
  27.  * @author Amy Roh
  28.  * @author Dmitri Valdin
  29.  * @version $Revision: 496190 $, $Date: 2007-01-14 16:21:45 -0700 (Sun, 14 Jan 2007) $
  30.  */
  31. public class CompressionResponseStream
  32.     extends ServletOutputStream {
  33.     // ----------------------------------------------------------- Constructors
  34.     /**
  35.      * Construct a servlet output stream associated with the specified Response.
  36.      *
  37.      * @param response The associated response
  38.      */
  39.     public CompressionResponseStream(HttpServletResponse response) throws IOException{
  40.         super();
  41.         closed = false;
  42.         this.response = response;
  43.         this.output = response.getOutputStream();
  44.     }
  45.     // ----------------------------------------------------- Instance Variables
  46.     /**
  47.      * The threshold number which decides to compress or not.
  48.      * Users can configure in web.xml to set it to fit their needs.
  49.      */
  50.     protected int compressionThreshold = 0;
  51.     /**
  52.      * Debug level
  53.      */
  54.     private int debug = 0;
  55.     /**
  56.      * The buffer through which all of our output bytes are passed.
  57.      */
  58.     protected byte[] buffer = null;
  59.     /**
  60.      * The number of data bytes currently in the buffer.
  61.      */
  62.     protected int bufferCount = 0;
  63.     /**
  64.      * The underlying gzip output stream to which we should write data.
  65.      */
  66.     protected OutputStream gzipstream = null;
  67.     /**
  68.      * Has this stream been closed?
  69.      */
  70.     protected boolean closed = false;
  71.     /**
  72.      * The content length past which we will not write, or -1 if there is
  73.      * no defined content length.
  74.      */
  75.     protected int length = -1;
  76.     /**
  77.      * The response with which this servlet output stream is associated.
  78.      */
  79.     protected HttpServletResponse response = null;
  80.     /**
  81.      * The underlying servket output stream to which we should write data.
  82.      */
  83.     protected ServletOutputStream output = null;
  84.     // --------------------------------------------------------- Public Methods
  85.     /**
  86.      * Set debug level
  87.      */
  88.     public void setDebugLevel(int debug) {
  89.         this.debug = debug;
  90.     }
  91.     /**
  92.      * Set the compressionThreshold number and create buffer for this size
  93.      */
  94.     protected void setBuffer(int threshold) {
  95.         compressionThreshold = threshold;
  96.         buffer = new byte[compressionThreshold];
  97.         if (debug > 1) {
  98.             System.out.println("buffer is set to "+compressionThreshold);
  99.         }
  100.     }
  101.     /**
  102.      * Close this output stream, causing any buffered data to be flushed and
  103.      * any further output data to throw an IOException.
  104.      */
  105.     public void close() throws IOException {
  106.         if (debug > 1) {
  107.             System.out.println("close() @ CompressionResponseStream");
  108.         }
  109.         if (closed)
  110.             throw new IOException("This output stream has already been closed");
  111.         if (gzipstream != null) {
  112.             flushToGZip();
  113.             gzipstream.close();
  114.             gzipstream = null;
  115.         } else {
  116.             if (bufferCount > 0) {
  117.                 if (debug > 2) {
  118.                     System.out.print("output.write(");
  119.                     System.out.write(buffer, 0, bufferCount);
  120.                     System.out.println(")");
  121.                 }
  122.                 output.write(buffer, 0, bufferCount);
  123.                 bufferCount = 0;
  124.             }
  125.         }
  126.         output.close();
  127.         closed = true;
  128.     }
  129.     /**
  130.      * Flush any buffered data for this output stream, which also causes the
  131.      * response to be committed.
  132.      */
  133.     public void flush() throws IOException {
  134.         if (debug > 1) {
  135.             System.out.println("flush() @ CompressionResponseStream");
  136.         }
  137.         if (closed) {
  138.             throw new IOException("Cannot flush a closed output stream");
  139.         }
  140.         if (gzipstream != null) {
  141.             gzipstream.flush();
  142.         }
  143.     }
  144.     public void flushToGZip() throws IOException {
  145.         if (debug > 1) {
  146.             System.out.println("flushToGZip() @ CompressionResponseStream");
  147.         }
  148.         if (bufferCount > 0) {
  149.             if (debug > 1) {
  150.                 System.out.println("flushing out to GZipStream, bufferCount = " + bufferCount);
  151.             }
  152.             writeToGZip(buffer, 0, bufferCount);
  153.             bufferCount = 0;
  154.         }
  155.     }
  156.     /**
  157.      * Write the specified byte to our output stream.
  158.      *
  159.      * @param b The byte to be written
  160.      *
  161.      * @exception IOException if an input/output error occurs
  162.      */
  163.     public void write(int b) throws IOException {
  164.         if (debug > 1) {
  165.             System.out.println("write "+b+" in CompressionResponseStream ");
  166.         }
  167.         if (closed)
  168.             throw new IOException("Cannot write to a closed output stream");
  169.         if (bufferCount >= buffer.length) {
  170.             flushToGZip();
  171.         }
  172.         buffer[bufferCount++] = (byte) b;
  173.     }
  174.     /**
  175.      * Write <code>b.length</code> bytes from the specified byte array
  176.      * to our output stream.
  177.      *
  178.      * @param b The byte array to be written
  179.      *
  180.      * @exception IOException if an input/output error occurs
  181.      */
  182.     public void write(byte b[]) throws IOException {
  183.         write(b, 0, b.length);
  184.     }
  185.     /**
  186.      * Write <code>len</code> bytes from the specified byte array, starting
  187.      * at the specified offset, to our output stream.
  188.      *
  189.      * @param b The byte array containing the bytes to be written
  190.      * @param off Zero-relative starting offset of the bytes to be written
  191.      * @param len The number of bytes to be written
  192.      *
  193.      * @exception IOException if an input/output error occurs
  194.      */
  195.     public void write(byte b[], int off, int len) throws IOException {
  196.         if (debug > 1) {
  197.             System.out.println("write, bufferCount = " + bufferCount + " len = " + len + " off = " + off);
  198.         }
  199.         if (debug > 2) {
  200.             System.out.print("write(");
  201.             System.out.write(b, off, len);
  202.             System.out.println(")");
  203.         }
  204.         if (closed)
  205.             throw new IOException("Cannot write to a closed output stream");
  206.         if (len == 0)
  207.             return;
  208.         // Can we write into buffer ?
  209.         if (len <= (buffer.length - bufferCount)) {
  210.             System.arraycopy(b, off, buffer, bufferCount, len);
  211.             bufferCount += len;
  212.             return;
  213.         }
  214.         // There is not enough space in buffer. Flush it ...
  215.         flushToGZip();
  216.         // ... and try again. Note, that bufferCount = 0 here !
  217.         if (len <= (buffer.length - bufferCount)) {
  218.             System.arraycopy(b, off, buffer, bufferCount, len);
  219.             bufferCount += len;
  220.             return;
  221.         }
  222.         // write direct to gzip
  223.         writeToGZip(b, off, len);
  224.     }
  225.     public void writeToGZip(byte b[], int off, int len) throws IOException {
  226.         if (debug > 1) {
  227.             System.out.println("writeToGZip, len = " + len);
  228.         }
  229.         if (debug > 2) {
  230.             System.out.print("writeToGZip(");
  231.             System.out.write(b, off, len);
  232.             System.out.println(")");
  233.         }
  234.         if (gzipstream == null) {
  235.             if (debug > 1) {
  236.                 System.out.println("new GZIPOutputStream");
  237.             }
  238.             if (response.isCommitted()) {
  239.                 if (debug > 1)
  240.                     System.out.print("Response already committed. Using original output stream");
  241.                 gzipstream = output;
  242.             } else {
  243.                 response.addHeader("Content-Encoding", "gzip");
  244.                 gzipstream = new GZIPOutputStream(output);
  245.             }
  246.         }
  247.         gzipstream.write(b, off, len);
  248.     }
  249.     // -------------------------------------------------------- Package Methods
  250.     /**
  251.      * Has this response stream been closed?
  252.      */
  253.     public boolean closed() {
  254.         return (this.closed);
  255.     }
  256. }