通過Filter和HttpServletResponseWrapper,實現Gzip壓縮

實現定製輸出的關鍵是對HttpServletResponse進行包裝,截獲所有輸出,等過濾器鏈處理完後,
Filter.doFilter,在截獲輸出進行處理,在寫入到真正的HttpServletResponse中。J2EE中已有
HttpServletResponseWrapper,使得包裝HttpServletResponse更加容易
public class GZipFilter implements Filter {
public void destroy() {
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
HttpServletResponse resp = (HttpServletResponse) response;
Wrapper wrapper = new Wrapper(resp);
chain.doFilter(request, wrapper);
byte[] gzipData = gzip(wrapper.getResponseData());
resp.addHeader("Content-Encoding", "gzip");
resp.setContentLength(gzipData.length);
ServletOutputStream output = response.getOutputStream();
output.write(gzipData);
output.flush();
}

private byte[] gzip(byte[] data) {
ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(10240);
GZIPOutputStream output = null;
try {
output = new GZIPOutputStream(byteOutput);
output.write(data);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
}
}
}
return byteOutput.toByteArray();
}

public void init(FilterConfig fConfig) throws ServletException {
}
}

public class Wrapper extends HttpServletResponseWrapper {
public static final int OT_NONE = 0, OT_WRITER = 1, OT_STREAM = 2;
private int outputType = OT_NONE;
private ServletOutputStream output = null;
private PrintWriter writer = null;
private ByteArrayOutputStream buffer = null;

public Wrapper(HttpServletResponse resp) throws IOException {
super(resp);
buffer = new ByteArrayOutputStream();
}

public PrintWriter getWriter() throws IOException {
if (outputType == OT_STREAM)
throw new IllegalStateException();
else if (outputType == OT_WRITER)
return writer;
else {
outputType = OT_WRITER;
writer = new PrintWriter(new OutputStreamWriter(buffer, getCharacterEncoding()));
return writer;
}
}

public ServletOutputStream getOutputStream() throws IOException {
if (outputType == OT_WRITER)
throw new IllegalStateException();
else if (outputType == OT_STREAM)
return output;
else {
outputType = OT_STREAM;
output = new WrappedOutputStream(buffer);
return output;
}
}

public void flushBuffer() throws IOException {
if (outputType == OT_WRITER)
writer.flush();
if (outputType == OT_STREAM)
output.flush();
}

public void reset() {
outputType = OT_NONE;
buffer.reset();
}

public byte[] getResponseData() throws IOException {
flushBuffer();
return buffer.toByteArray();
}
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();
}
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章