zoukankan      html  css  js  c++  java
  • 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>
    
     



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


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




  • 相关阅读:
    linux下mysql定时备份数据库
    怎么不让别人ping服务器
    忘记了本地mysql密码应该怎么找回
    配置 centos apache 的日志文件为每天保存,在home分区
    Android 开发环境安装配置手册
    jquery定时器
    谷歌浏览器控制台出现 Unchecked runtime.lastError: The message port closed before a response was received. 的报错
    百度文库下载文档没有下载劵解决
    JRebel安装部署,激活
    用Cygwin实现在window环境下使用Linux命令-nohup 来后台运行程序
  • 原文地址:https://www.cnblogs.com/Baronboy/p/5402144.html
Copyright © 2011-2022 走看看