Gzip 服務端壓縮數據,提升傳輸速率。java
首先寫一個過濾器數組
public class GzipValidator implements Filter{ @Override public void destroy() { } @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request= (HttpServletRequest) arg0 ; HttpServletResponse response = (HttpServletResponse) arg1; CachedResponseWrapper responseWrapper = null ; responseWrapper = new CachedResponseWrapper(response); filterChain.doFilter(request, responseWrapper); byte[] responseData = responseWrapper.getResponseData(); System.out.println(responseData.length); //壓縮數據 responseData=compress(request, responseWrapper, responseData); System.out.println(responseData.length); //發送數據 response.setContentLength(responseData.length); response.setHeader("Content-Encoding", "gzip"); ServletOutputStream output = response.getOutputStream(); //由於是包裝事後的因此要從新輸出 output.write(responseData); output.flush(); output.close(); } public byte[] compress(HttpServletRequest request, HttpServletResponse response, byte[] responseData){ String acceptEncoding = request.getHeader("Accept-Encoding"); if ( acceptEncoding == null ||!acceptEncoding.contains("gzip")) { return responseData; } response.setHeader("Content-Encoding", "gzip"); return GzipUtil.gzip(responseData); } @Override public void init(FilterConfig arg0) throws ServletException { } } GzipUtil 類 public class GzipUtil { public static byte[] gzip(byte[] data){ ByteArrayOutputStream byteOutput=new ByteArrayOutputStream(10240); GZIPOutputStream output =null; try { output = new GZIPOutputStream(byteOutput); output.write(data); } catch (IOException e) { throw new RuntimeException("Gzip failed.", e); } finally { if (output != null) { try { output.close(); } catch (IOException e) { } } } return byteOutput.toByteArray();//將字節流轉換爲byte數組 } } CachedResponseWrapper類 public class CachedResponseWrapper extends HttpServletResponseWrapper{ /** * Indicate that getOutputStream() or getWriter() is not called yet. */ public static final int OUTPUT_NONE = 0; /** * Indicate that getWriter() is already called. */ public static final int OUTPUT_WRITER = 1; /** * Indicate that getOutputStream() is already called. */ public static final int OUTPUT_STREAM = 2; private int outputType = OUTPUT_NONE; private int status = SC_OK; private ServletOutputStream output = null; private PrintWriter writer = null; private ByteArrayOutputStream buffer = null; public CachedResponseWrapper(HttpServletResponse resp) throws IOException { super(resp); buffer = new ByteArrayOutputStream(); } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public void setStatus(int status, String string) { super.setStatus(status, string); this.status = status; } public void sendError(int status, String string) throws IOException { super.sendError(status, string); this.status = status; } public void sendError(int status) throws IOException { super.sendError(status); this.status = status; } public void sendRedirect(String location) throws IOException { super.sendRedirect(location); this.status = SC_MOVED_TEMPORARILY; } public PrintWriter getWriter() throws IOException { if (outputType == OUTPUT_STREAM) throw new IllegalStateException(); else if (outputType == OUTPUT_WRITER) return writer; else { outputType = OUTPUT_WRITER; writer = new PrintWriter(new OutputStreamWriter(buffer, getCharacterEncoding())); return writer; } } public ServletOutputStream getOutputStream() throws IOException { if (outputType == OUTPUT_WRITER) throw new IllegalStateException(); else if (outputType == OUTPUT_STREAM) return output; else { outputType = OUTPUT_STREAM; output = new WrappedOutputStream(buffer); return output; } } public void flushBuffer() throws IOException { if (outputType == OUTPUT_WRITER) writer.flush(); if (outputType == OUTPUT_STREAM) output.flush(); } public void reset() { outputType = OUTPUT_NONE; buffer.reset(); } /** * Call this method to get cached response data. * * @return byte array buffer. * @throws IOException */ public byte[] getResponseData() throws IOException { flushBuffer(); return buffer.toByteArray(); } /** * This class is used to wrap a ServletOutputStream and store output stream * in byte[] buffer. */ class WrappedOutputStream extends ServletOutputStream { private ByteArrayOutputStream buffer; public WrappedOutputStream(ByteArrayOutputStream buffer) { this.buffer = buffer; } public void write(int b) throws IOException { buffer.write(b); } public byte[] toByteArray() { return buffer.toByteArray(); } } }
遇到的問題:發送數據的時候先設置相應數據的長度再得到包裝以後的輸出流。app