Last active
August 29, 2015 14:16
-
-
Save jasonsperske/b5e2c4b998239878580c to your computer and use it in GitHub Desktop.
A flexible compression filter for Tomcat web apps created by http://stackoverflow.com/a/11068672/16959
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CompressionFilter implements Filter { | |
public void destroy() {} | |
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { | |
HttpServletRequest httpRequest = (HttpServletRequest) request; | |
HttpServletResponse httpResponse = (HttpServletResponse) response; | |
String acceptEncoding = httpRequest.getHeader(HttpHeaders.ACCEPT_ENCODING); | |
if (acceptEncoding != null) { | |
if (acceptEncoding.indexOf("gzip") >= 0) { | |
GZIPHttpServletResponseWrapper gzipResponse = new GZIPHttpServletResponseWrapper(httpResponse); | |
chain.doFilter(request, gzipResponse); | |
gzipResponse.finish(); | |
return; | |
} | |
} | |
chain.doFilter(request, response); | |
} | |
public void init(FilterConfig filterConfig) throws ServletException {} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GZIPHttpServletResponseWrapper extends HttpServletResponseWrapper { | |
private ServletResponseGZIPOutputStream gzipStream; | |
private ServletOutputStream outputStream; | |
private PrintWriter printWriter; | |
public GZIPHttpServletResponseWrapper(HttpServletResponse response) throws IOException { | |
super(response); | |
response.addHeader(HttpHeaders.CONTENT_ENCODING, "gzip"); | |
} | |
public void finish() throws IOException { | |
if (printWriter != null) { | |
printWriter.close(); | |
} | |
if (outputStream != null) { | |
outputStream.close(); | |
} | |
if (gzipStream != null) { | |
gzipStream.close(); | |
} | |
} | |
@Override | |
public void flushBuffer() throws IOException { | |
if (printWriter != null) { | |
printWriter.flush(); | |
} | |
if (outputStream != null) { | |
outputStream.flush(); | |
} | |
super.flushBuffer(); | |
} | |
@Override | |
public ServletOutputStream getOutputStream() throws IOException { | |
if (printWriter != null) { | |
throw new IllegalStateException("printWriter already defined"); | |
} | |
if (outputStream == null) { | |
initGzip(); | |
outputStream = gzipStream; | |
} | |
return outputStream; | |
} | |
@Override | |
public PrintWriter getWriter() throws IOException { | |
if (outputStream != null) { | |
throw new IllegalStateException("printWriter already defined"); | |
} | |
if (printWriter == null) { | |
initGzip(); | |
printWriter = new PrintWriter(new OutputStreamWriter(gzipStream, getResponse().getCharacterEncoding())); | |
} | |
return printWriter; | |
} | |
@Override | |
public void setContentLength(int len) { | |
} | |
private void initGzip() throws IOException { | |
gzipStream = new ServletResponseGZIPOutputStream(getResponse().getOutputStream()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ServletResponseGZIPOutputStream extends ServletOutputStream { | |
GZIPOutputStream gzipStream; | |
final AtomicBoolean open = new AtomicBoolean(true); | |
OutputStream output; | |
public ServletResponseGZIPOutputStream(OutputStream output) throws IOException { | |
this.output = output; | |
gzipStream = new GZIPOutputStream(output); | |
} | |
@Override | |
public void close() throws IOException { | |
if (open.compareAndSet(true, false)) { | |
gzipStream.close(); | |
} | |
} | |
@Override | |
public void flush() throws IOException { | |
gzipStream.flush(); | |
} | |
@Override | |
public void write(byte b[]) throws IOException { | |
write(b, 0, b.length); | |
} | |
@Override | |
public void write(byte b[], int off, int len) throws IOException { | |
if (!open.get()) { | |
throw new IOException("Stream closed!"); | |
} | |
gzipStream.write(b, off, len); | |
} | |
@Override | |
public void write(int b) throws IOException { | |
if (!open.get()) { | |
throw new IOException("Stream closed!"); | |
} | |
gzipStream.write(b); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<filter> | |
<filter-name>CompressionFilter</filter-name> | |
<filter-class>com.my.company.CompressionFilter</filter-class> | |
</filter> | |
<filter-mapping> | |
<filter-name>CompressionFilter</filter-name> | |
<url-pattern>*.js</url-pattern> | |
</filter-mapping> | |
<filter-mapping> | |
<filter-name>CompressionFilter</filter-name> | |
<url-pattern>*.css</url-pattern> | |
</filter-mapping> | |
<filter-mapping> | |
<filter-name>CompressionFilter</filter-name> | |
<url-pattern>*.html</url-pattern> | |
</filter-mapping> | |
<filter-mapping> | |
<filter-name>CompressionFilter</filter-name> | |
<url-pattern>*.jsp</url-pattern> | |
</filter-mapping> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment