1. 压缩 Filter
// GZIPFilter.java
package org.demo.filter; import java.io.IOException; 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; /** * Filter that compress output with gzip. * Code from http://www.onjava.com/pub/a/onjava/2003/11/19/filters.html * @author dycc * */ public class GZIPFilter implements Filter{ @Override public void init(FilterConfig arg0) throws ServletException { // No operation. } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { if (req instanceof HttpServletRequest){ HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp; // check for gzip capability String ac = request.getHeader("accept-encoding"); if (ac == null || ac.indexOf("gzip") == -1){ // not support gzip. chain.doFilter(request, response); } else { // support gzip. GZIPResponseWrapper wrappedResp = new GZIPResponseWrapper(response); chain.doFilter(request, wrappedResp); wrappedResp.finish(); } } } @Override public void destroy() { // No operation. } }
// GZIPResponseWrapper.java
package org.demo.filter; 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; /** * Wrap for GZIPFilter * @author dycc * */ public class GZIPResponseWrapper extends HttpServletResponseWrapper{ protected HttpServletResponse original_resp = null; protected ServletOutputStream stream = null; protected PrintWriter writer = null; public GZIPResponseWrapper(HttpServletResponse response) { super(response); this.original_resp = response; } @Override public ServletOutputStream getOutputStream() throws IOException { if (writer != null){ throw new IllegalStateException("getWriter() has already been called."); } if (stream == null){ stream = new GZIPResponseStream(original_resp); } return stream; } @Override public PrintWriter getWriter() throws IOException { if (stream != null){ throw new IllegalStateException("getOutputStream() has already been called."); } if (writer == null){ writer = new PrintWriter( new OutputStreamWriter( new GZIPResponseStream(original_resp),"UTF-8")); } return writer; } @Override public void flushBuffer() throws IOException { if (stream != null){ stream.flush(); } else if (writer != null){ writer.flush(); } } public void finish(){ try { if (stream != null){ stream.close(); } else if (writer != null){ writer.close(); } } catch (IOException e){ // Ignore. } } }
// GZIPResponseStream.java
package org.demo.filter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; /** * Wrap response stream for GZIPFilter * @author dycc * */ public class GZIPResponseStream extends ServletOutputStream{ protected HttpServletResponse response = null; protected ServletOutputStream out = null; protected ByteArrayOutputStream baos = null; protected GZIPOutputStream gzipos = null; protected boolean closed = false; public GZIPResponseStream(HttpServletResponse response)throws IOException{ super(); this.response = response; this.out = response.getOutputStream(); this.baos = new ByteArrayOutputStream(); this.gzipos = new GZIPOutputStream(this.baos); this.closed = false; } @Override public void write(int b) throws IOException { if (closed){ throw new IOException("Cannot write to a closed output stream."); } gzipos.write(b); } @Override public void write(byte[] b) throws IOException { write(b,0,b.length); } @Override public void write(byte[] buf, int off, int len) throws IOException { if (closed){ throw new IOException("Cannot write to a closed output stream."); } gzipos.write(buf, off, len); } @Override public void flush() throws IOException { if (closed){ throw new IOException("Cannot flush a closed output stream."); } gzipos.flush(); } @Override public void close() throws IOException { if (closed){ return; } gzipos.finish(); byte[] buf = this.baos.toByteArray(); response.addHeader("Content-Length", Integer.toString(buf.length)); response.addHeader("Content-Encoding", "gzip"); out.write(buf); out.flush(); out.close(); closed = true; } }
2. END