servlet--统一对全站的数据进行压缩
?
Filter实现,这里需要从写父类的HttpServletResponse的response
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.HttpServletRequestWrapper;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;public class GzipFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {// 0 强转HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;//提供自定义缓存,提供自定义response,和自定义的流,将数据写入到自定义的缓存中,然后将数据压缩之后,给tomcat的流,将数据发送//1提供自定义缓存--提供字节数组final ByteArrayOutputStream customBuffer = new ByteArrayOutputStream();//2自定义responseHttpServletResponse myResponse = new HttpServletResponseWrapper(response){//匿名内部类的内部内容//重新getOutputStream@Overridepublic ServletOutputStream getOutputStream() throws IOException {return new ServletOutputStream(){@Overridepublic void write(int b) throws IOException {//需要将数据存放到自定义缓存中customBuffer.write(b);}};}private PrintWriter pw;@Overridepublic PrintWriter getWriter() throws IOException {pw = new PrintWriter(new OutputStreamWriter(getOutputStream(),getCharacterEncoding()));return pw;}@Overridepublic void flushBuffer() throws IOException {if(pw != null){pw.flush();}}};//3.放行chain.doFilter(request, myResponse); //往自定义缓存写入数据//4获得数据byte[] servletData = customBuffer.toByteArray();//5压缩// * 存放压缩数据的流ByteArrayOutputStream gzipBAOS = new ByteArrayOutputStream();GZIPOutputStream gzipOut = new GZIPOutputStream(gzipBAOS);// * 压缩数据gzipOut.write(servletData);gzipOut.close();// * 获得要锁之后的数据byte[] gzipData = gzipBAOS.toByteArray();//6然后发送// * 请求头,Accept-Encoding: gzip,表示浏览器支持的压缩格式// * 通知浏览器发送的数据为压缩格式response.setHeader("content-encoding", "gzip");response.getOutputStream().write(gzipData);}@Overridepublic void destroy() {}}
?servlet测试代码:
import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class GzipGetDataServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {this.doPost(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");//将90w字节发送到浏览器StringBuilder builder = new StringBuilder();for(int i =0 ; i < 1000 ; i ++){builder.append("屌丝逆袭<br/>");}//response.getOutputStream().print(builder.toString());response.getWriter().print(builder.toString());}}
?
?