动态代理应用-过滤器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的主要内容,如果未能解决你的问题,请参考以下文章

使用动态代理解决全局乱码

servlet,过滤器,监听器,拦截器的区别

使用动态代理对象进行敏感字过滤

AOP与动态代理

js简洁代码片段

SpringCloud06_Gateway的概述工程案例代码微服务动态路由Predicate的使用详解Filter(建议收藏)