• Java代码:response压缩响应


    思路:

    1、通过filter向目标页面传递一个自定义的response对象 2.、在这个response对象中通过重写getOutputStream方法和getWriter方法使目标资源调用
    该方法输出页面内容时,获得我们自定义的ServletOutputStream对象
    3、在我们自己定义的ServletOutputStream中,重写writer 方法,使资源写到buffer中。
    4、当页面完成输出后,在filter中就可以得到页面写出的数据,从而我们可以调用GZIPOutputStream
    对数据进行压缩后再传递给浏览器,完成响应文件的压缩功能

    目的:减少浏览器的响应时间以及节省带宽


    1、showServlet类:

    public class ShowServlet extends HttpServlet {
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		//获得response的输出流
    		ServletOutputStream sout=response.getOutputStream();
    		//字符串转化为字节输出
    		sout.write("AAAAAAAfwef fds asdfsdaf sdfa sdfasd sadf AAAAAAAAAAAAAAAAAAAAAAAAAAAAA".getBytes());
    	}
    }
    


    2、MyResponse类:


    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpServletResponseWrapper;
    
    	/*HttpServletResponseWrapper
    	是一个Decoretor设计模式的默认实现类
    	不需要像实现request接口中的所有方法
    	以下为装饰类的做法
    	*/
    public class MyResponse extends HttpServletResponseWrapper {
    	private HttpServletResponse response;
    	private ByteArrayOutputStream bout=new ByteArrayOutputStream();
    	
    	public MyResponse(HttpServletResponse response) {
    		super(response);
    		this.response=response;
    	}
    	
    	/*综合考虑下还是重写getOutStream
    	但是需求是要输出到缓存,此方法不适合,于是写一个拓展类类来迎合需求*/
    	@Override
    	public ServletOutputStream getOutputStream() throws IOException {
    		return new MyServletOutputStream(bout);
    	}
    	
    	
    	//将数据封装成一个数组然后发送到缓存
    	class MyServletOutputStream extends ServletOutputStream{
    		private ByteArrayOutputStream bout;
    		public MyServletOutputStream(ByteArrayOutputStream bout){
    			this.bout=bout;
    			
    		}
    		
    		/*此处应该要将数据包装成一个数组但是
    			此处不符合需求,于是重载*/
    		@Override
    		public void write(int b) throws IOException {
    			
    		}
    		public void write(byte[] bytes) throws IOException {
    			bout.write(bytes);
    			bout.flush();
    			bout.close();
    		}
    		
    		
    	}
    	public byte[] getBuffer() {
    		return bout.toByteArray();
    	}
    }
    



    3、GZIPFilter过滤类:



    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.util.zip.GZIPOutputStream;
    
    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;
    
    public class GZIPFilter implements Filter {
    	@Override
    	public void destroy() {
    	}
    
    	@Override
    	public void doFilter(ServletRequest req, ServletResponse res,
    			FilterChain chain) throws IOException, ServletException {
    	//转化为子类才能处理,此处用了强制类型转换
    	HttpServletRequest request=(HttpServletRequest) req;
    	HttpServletResponse response=(HttpServletResponse) res;
    	
    	//创建MyResponse
    	MyResponse myResponse=new MyResponse(response);
    	
    	
    	//此处放行的response是处理过的response
    	chain.doFilter(request, myResponse);
    	
    	
    	//在输出到浏览器之前将输过来的buffer进行压缩
    	//增加getBuffer方法
    	byte[] bytes=myResponse.getBuffer();
    	//输出压缩前的长度以作对比
    	System.out.println("压缩前"+bytes.length);
    	
    	//用GZIPOutputStream压缩
    	ByteArrayOutputStream bout=new ByteArrayOutputStream();
    	GZIPOutputStream gzip=new GZIPOutputStream(bout);
    	
    	gzip.write(bytes);
    
    	//一般输出都要flush
    	gzip.flush();
    	gzip.close();
    	bytes=bout.toByteArray();
    	//压缩后
    	System.out.println("压缩后"+bytes.length);
    	
    	//注明压缩类型
    	response.setHeader("content-encoding", "gzip");
    	response.setHeader("content-length",bytes.length+"");
    	//写到浏览器,浏览器会自动解压,只要注明了类型
    	response.getOutputStream().write(bytes);
    	
    
    	}
    
    	@Override
    	public void init(FilterConfig filterConfig) throws ServletException {
    
    	}
    
    }
    



    其中在xml配置文件中应该添加以下代码

    	 <filter>
    	 	<filter-name>GZIPFilter</filter-name>
    	 	<filter-class>a2.GZIPFilter</filter-class>
    	 </filter>
    	
    	<filter-mapping>
    		<filter-name>GZIPFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    
     



    控制台输出(显示压缩的效果)


    浏览器输出(显示响应报文)




  • 相关阅读:
    Codeforces 722C. Destroying Array
    Codeforces 722D. Generating Sets
    【BZOJ】3436: 小K的农场
    数论四·扩展欧几里德
    数论三·约瑟夫问题
    数论二·Eular质数筛法
    #1287 : 数论一·Miller-Rabin质数测试
    树的维护
    可持久化线段树
    【NOIP2016】天天爱跑步
  • 原文地址:https://www.cnblogs.com/Baronboy/p/5402144.html
Copyright © 2020-2023  润新知