动态代理应用-过滤器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方法的数据都进入缓冲区。
时间: 2024-10-10 02:38:29

动态代理应用-过滤器Filter的相关文章

在Filter中使用动态代理解决请求中文乱码问题

使用动态代理解决请求中文乱码问题 1.增强一个类我们常用的几种解决方案: 1.继承 a) 优点简单 b) 必须有被增强类的实现类 2.装饰者模式 a) 要求:1实现相同的接口.2持有被增强的对象 b) 优点:不必知道被增强的实现是谁 c) 缺点:必须实现所有没被增强方法的原始对象的原样调用 3.动态代理 a) 要求:1实现相同接口,2持有被增强的对象 b) 优点:不必手动实现所有不增强方法的原样调用.对方法进行增强时有类似过滤器的功能. c) 缺点:学习成本高. 代理(Proxy): 一个代理对

利用filter和动态代理解决全站乱码问题

1.利用filter和动态代理解决全站乱码问题 1.1filter的代码 package com.baowei.filter; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import javax.servlet.Filter; import javax.servlet

动态代理AOP实现方法过滤

上一节实现了动态代理,接下来 有时候,我不需要在每一个方法都要记录日志,做权限验证 等等. 所有就有了这样的需求.AOP实现特定方法过滤,有选择性的来对方法实现AOP 拦截.就是本节标题所示. 举个例子,对于查询的方法我不需要记录日志,所以,我就找到如果以"Get"开头的方法,就不记录日志,否则就记录日志:所以基于这样一个需求,代码如下: public override IMessage Invoke(IMessage msg) {   var methodCall = msg as

深入分析JavaWeb Item36 -- 过滤器Filter高级应用

在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目标资源,从而实现一些特殊需求. 一.Decorator设计模式 1.1.Decorator设计模式介绍 当某个对象的方法不适应业务需求时,通常有2种方式可以对方法进行增强: 编写子类,覆盖需增强的方法. 使用Decorator设计模式对方法进行增强. 使用代理 在阎宏博士的<JAVA与模式>一书中

Java代理/静态代理/动态代理/代理模式

代理模式:即Proxy Pattern,常用的设计模式之一.代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问. 代理概念 :为某个对象提供一个代理,以控制对这个对象的访问. 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代.代理类负责请求的预处理.过滤.将请求分派给委托类处理.以及委托类执行完请求后的后续处理. 下面以明星为例模拟需求说明静态代理和动态代理. 一.首先看静态代理 看下图:歌迷希望明星许巍唱歌(许巍即是目标对象),但不可能直接找

Java代理之(jdk静态代理/jdk动态代理/cglib动态代理/aop/aspectj)

一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法.如果公司卖多少钱,代理商也卖多少钱,那么代理商就赚不了钱.所以代理商在调用公司的卖方法后,加上自己的利润然后再把产品卖给客户.而客户部直接跟公司打交道,或者客户根本不知道公司的存在,然而客户最终却买到了产品. 专业点说:代理模式是对象的结构型模式,代码模式给某一个对象提供代理,并由代理对象控制原对象

Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)

一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法.如果公司卖多少钱,代理商也卖多少钱,那么代理商就赚不了钱.所以代理商在调用公司的卖方法后,加上自己的利润然后再把产品卖给客户.而客户部直接跟公司打交道,或者客户根本不知道公司的存在,然而客户最终却买到了产品. 专业点说:代理模式是对象的结构型模式,代码模式给某一个对象提供代理,并由代理对象控制原对象

实现动态代理的两种方式介绍+例子demo(JDK、CGlib)

JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢? 这就需要CGLib了.CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑. JDK动态代理与CGLib动态代理均是实现Spring AOP的基础. 一.JDK这种方式动态代理 1. 没引入spring配置文件时,怎么实现JDK动态代理 情景介绍:如何解决全站中文乱码问题? 我们会定义一个过滤器:Character

Spring AOP高级——源码实现(1)动态代理技术

在正式进入Spring AOP的源码实现前,我们需要准备一定的基础也就是面向切面编程的核心——动态代理. 动态代理实际上也是一种结构型的设计模式,JDK中已经为我们准备好了这种设计模式,不过这种JDK为我们提供的动态代理有2个缺点: 只能代理实现了接口的目标对象: 基于反射,效率低 鉴于以上2个缺点,于是就出现了第二种动态代理技术——CGLIB(Code Generation Library).这种代理技术一是不需要目标对象实现接口(这大大扩展了使用范围),二是它是基于字节码实现(这比反射效率高