package com.tinysoft.cn;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
*
* @author 董乐强 2017-7-30 文本压缩过滤器的实现
*/
public class GzipFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) resp;
} catch (Exception e) {
throw new RuntimeException("non-http request");
}
// 要对响应到,浏览器的数据进行压缩,则必须获得拦截到响应到浏览器的数据
// 所以必须对response进行包装,然后将返回的数据保存到内存流中,进行缓存
// 从而我们可以从内存流中截取response封装的数据,燃后进行压缩处理之后,返回给浏览器
MyHttpServletResponse myresponse = new MyHttpServletResponse(response);
// 我要拦截response对象,则在放行之后,进行拦截
chain.doFilter(request, myresponse);
// 要对响应到,浏览器的数据进行压缩,则必须获得拦截到响应到浏览器的数据
// 所以必须对response进行包装,才可以
byte b[] = myresponse.getBytes();
System.out.println("压缩前大小:" + b.length);
// 将数据压缩到内存流中去
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream(out);
gout.write(b);
gout.close();
// 从内存流中去压缩数据
b = out.toByteArray();
System.out.println("压缩后大小:" + b.length);
// 通知浏览器正文的压缩格式
response.setHeader("Content-Encoding", "gzip");
// 将压缩后的数据写回到浏览器
response.getOutputStream().write(b);
}
public void destroy() {
// TODO Auto-generated method stub
}
}
class MyHttpServletResponse extends HttpServletResponseWrapper {
private HttpServletResponse response;
// 将response输出到浏览器的数据,先保存到内存流中就行缓存
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 字符输出流
private PrintWriter pw;
public MyHttpServletResponse(HttpServletResponse response) {
super(response);
this.response = response;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new MyServletOutputStream(baos);
}
@Override
public PrintWriter getWriter() throws IOException {
pw = new PrintWriter(new OutputStreamWriter(baos,
response.getCharacterEncoding()));
return pw;
}
// 将内存流输出,得到结果
public byte[] getBytes() {
try {
if (pw != null)
pw.close();
baos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return baos.toByteArray();
}
}
// 在一次进行包装,将数据写到内存流中
class MyServletOutputStream extends ServletOutputStream {
private ByteArrayOutputStream baos;
public MyServletOutputStream(ByteArrayOutputStream baos) {
this.baos = baos;
}
@Override
public void write(int b) throws IOException {
// 写到内存流中去
baos.write(b);
}
}
文本压缩过滤器实现
最新推荐文章于 2023-07-27 09:18:38 发布