动态代理练习2-全站压缩流输出[response动态代理]
全站压缩流输出[response动态代理]
1、普通类-代理类
1 import java.io.ByteArrayOutputStream; 2 import java.io.IOException; 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 import java.util.zip.GZIPOutputStream; 7 8 import javax.servlet.Filter; 9 import javax.servlet.FilterChain; 10 import javax.servlet.FilterConfig; 11 import javax.servlet.ServletException; 12 import javax.servlet.ServletOutputStream; 13 import javax.servlet.ServletRequest; 14 import javax.servlet.ServletResponse; 15 import javax.servlet.http.HttpServletRequest; 16 import javax.servlet.http.HttpServletResponse; 17 18 public class GzipFilter implements Filter { 19 20 public void init(FilterConfig arg0) throws ServletException { 21 } 22 public void destroy() { 23 } 24 public void doFilter(ServletRequest req , ServletResponse res,FilterChain chain) throws IOException, ServletException { 25 26 HttpServletRequest request = (HttpServletRequest) req; 27 HttpServletResponse response = (HttpServletResponse) res; 28 MyResponse myResponse = new MyResponse(response); 29 chain.doFilter(request, myResponse.getProxy()); 30 // 取得缓存中的数据 31 byte[] buf = myResponse.getBuffer(); 32 System.out.println("压缩前:" + buf.length); 33 //以下是压缩代码 34 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 35 GZIPOutputStream gout = new GZIPOutputStream(bout); 36 gout.write(buf); 37 gout.flush(); 38 gout.close(); 39 // 取得压缩后的数据 40 buf = bout.toByteArray(); 41 System.out.println("压缩后:" + buf.length); 42 // 向浏览器发送压缩后的数据 43 response.setHeader("content-encoding", "gzip"); 44 response.setHeader("content-length", buf.length+""); 45 response.getOutputStream().write(buf); 46 } 47 } 48 // 1、一个普通类不实现任何接口-代理类 49 class MyResponse{ 50 // 缓存 51 private ByteArrayOutputStream bout = new ByteArrayOutputStream(); 52 //取得缓存中的数据 53 public byte[] getBuffer(){ 54 return bout.toByteArray(); 55 } 56 // 2、代理对象的引用 57 private HttpServletResponse response; 58 // 3、通过构造器初始化代理对象 59 public MyResponse(HttpServletResponse response){ 60 this.response = response; 61 } 62 // 4、写一个普通方法,该方法的返回值是接口,该接口是目标对象的实现接口 63 public HttpServletResponse getProxy(){ 64 65 return (HttpServletResponse) Proxy.newProxyInstance( 66 MyResponse.class.getClassLoader(),//1、由哪个类加载器加载 67 response.getClass().getInterfaces(), //2、被代理类的方法 68 new InvocationHandler() { 69 70 public Object invoke( 71 Object proxy,//1、被代理的对象 72 Method method, //2、被代理的方法 73 Object[] args//3、被代理方法的参数 74 )throws Throwable { 75 76 if("getOutputStream".equals(method.getName())){ 77 return new MyServletOutputStream(bout); 78 } 79 return null; 80 } 81 }); 82 } 83 } 84 // 带有缓存功能的ServletOutputStream 85 class MyServletOutputStream extends ServletOutputStream{ 86 87 private ByteArrayOutputStream bout; 88 public MyServletOutputStream(ByteArrayOutputStream bout) { 89 this.bout = bout; 90 } 91 @Override 92 public void write(int b) throws IOException { 93 } 94 //将字节数据写入缓存 95 public void write(byte[] buf) throws IOException{ 96 bout.write(buf); 97 bout.flush(); 98 } 99 }
2、Servlet
1 import java.io.IOException; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.ServletOutputStream; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class ShowServlet extends HttpServlet { 10 11 public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException { 12 13 ServletOutputStream sout = response.getOutputStream(); 14 sout.write("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ".getBytes()); 15 } 16 }
3、web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5" 3 xmlns="http://java.sun.com/xml/ns/javaee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 6 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 7 <filter> 8 <filter-name>MyGzipFilte</filter-name> 9 <filter-class>cn.zengfanshegn.proxy.servlet.GzipFilter</filter-class> 10 </filter> 11 <filter-mapping> 12 <filter-name>MyGzipFilte</filter-name> 13 <servlet-name>ShowServlet</servlet-name> 14 </filter-mapping> 15 16 <servlet> 17 <servlet-name>ShowServlet</servlet-name> 18 <servlet-class>cn.zengfanshegn.proxy.servlet.ShowServlet</servlet-class> 19 </servlet> 20 <servlet-mapping> 21 <servlet-name>ShowServlet</servlet-name> 22 <url-pattern>/ShowServlet</url-pattern> 23 </servlet-mapping> 24 </web-app>
by hacket