动态代理应用-过滤器Filter
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态代理应用-过滤器Filter相关的知识,希望对你有一定的参考价值。
在过滤器的应用中,有时需要对web的两个重要隐式对象request,response进行增强,可以采用包装设计模式,实现HttpServletRequestWrapper或者HttpServletResponseWrapper,重写某些方法进行增强。采用动态代理可以解决以上问题。
1.解决全站乱码问题
1 @Override 2 public void doFilter(ServletRequest req, ServletResponse resp, 3 FilterChain chain) throws IOException, ServletException { 4 final HttpServletRequest request=(HttpServletRequest) req; 5 HttpServletResponse response=(HttpServletResponse) resp; 6 request.setCharacterEncoding("utf-8"); 7 8 chain.doFilter((ServletRequest) Proxy.newProxyInstance(CharacterEncodingFilter.class.getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() { 9 10 @Override 11 public Object invoke(Object proxy, Method method, Object[] args) 12 throws Throwable { 13 if(!method.getName().equals("getParameter")){ 14 return method.invoke(request, args); 15 } 16 if(!request.getMethod().equalsIgnoreCase("get")){ 17 return method.invoke(request, args); 18 } 19 20 String value=(String) method.invoke(request, args); 21 if(value==null){ 22 return null; 23 } 24 return new String(value.getBytes("iso8859-1"),"UTF-8"); 25 } 26 }), response); 27 }
dofilter方法中对request.getPamarater()方法(
request.getClass().getInterfaces()
)进行了增强,对过滤器进行全站配置,对每一个request进行拦截,将iso8859-1转为UTF-8的格式,彻底解决中文乱码问题。
2、压缩过滤器
1 @Override 2 public void doFilter(ServletRequest req, ServletResponse resp, 3 FilterChain chain) throws IOException, ServletException { 4 final HttpServletRequest request = (HttpServletRequest) req; 5 final HttpServletResponse response = (HttpServletResponse) resp; 6 ResponseProxy proxy=new ResponseProxy(response); 7 chain.doFilter(request, proxy.createProxy()); 8 9 byte[]out=proxy.getBuffer();//得到目标资源的输出 10 11 System.out.println(new String(out,"UTF-8")); 12 13 } 14 class ResponseProxy{ 15 private ByteArrayOutputStream bout=new ByteArrayOutputStream(); 16 private PrintWriter pw=null; 17 public byte[] getBuffer(){ 18 if(pw!=null){ 19 pw.close(); 20 } 21 return bout.toByteArray(); 22 } 23 private HttpServletResponse response; 24 public ResponseProxy(HttpServletResponse response){ 25 this.response=response; 26 } 27 28 public HttpServletResponse createProxy(){ 29 return (HttpServletResponse) Proxy.newProxyInstance(GzipFilter.class.getClassLoader(), response.getClass().getInterfaces(), new InvocationHandler() { 30 31 @Override 32 public Object invoke(Object proxy, Method method, Object[] args) 33 throws Throwable { 34 if(!method.getName().equals("getWriter") && !method.getName().equals("getOutputStream")){ 35 method.invoke(response, args); 36 } 37 if(method.getName().equals("getWriter")){ 38 pw=new PrintWriter(new OutputStreamWriter(bout, "utf-8")); 39 return pw; 40 } 41 if(method.getName().equals("getOutputStream")){ 42 return new ServletOutputStream() { 43 44 @Override 45 public void write(int b) throws IOException { 46 bout.write(b); 47 } 48 }; 49 } 50 return null; 51 } 52 }); 53 } 54 }
dofilter方法中对response对象(
response.getClass().getInterfaces()
)进行了增强,定义了一个缓冲区,控制response的getWriter和getOutputStream方法的数据都进入缓冲区。
以上是关于动态代理应用-过滤器Filter的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud06_Gateway的概述工程案例代码微服务动态路由Predicate的使用详解Filter(建议收藏)