Java 代理模式-JDK动态代理-实现对请求中文乱码的处理

Java中的设计模式之–代理模式
1.代理:与我们平常听说的代理基本上是一个意思,例如:微商现在是许多人实现梦想的一个重要平台,从厂商—-代理—-客户三者之间来进行商品交易。代理就是为厂商提供客户,厂商为代理提供商品,以及佣金报酬。
2.代理模式能够解决什么问题呢?
代理模式在Java中用于对一个类的增强,具体是对方法的增强。那么微商中,有些商品可以在销售中需要做一些过滤,比如某些商品只对学生销售,厂商并不去做这件事情,而是代理人自己去处理,这样通过代理人去处理业务逻辑,而不影响商品销售这件事情,客户在厂商那里能够买到东西,通过代理人也能够买到东西,这种模式被称之为代理模式。
3.Java中的代理模式:
JDK中提供的Proxy代理类,由Java.lang.reflect.Proxy提供动态创建代理的方法`Proxy.newProxyInstance(ClassLoader, Class

静态代理实现对查询结果的判空处理:
实现条件:
    ①需要存在提供方法的接口,委托类与代理类实现同一个接口
    ②代理类中需要有委托类的对象的引用。
接口:UserDao层的接口,提供查询等方法。
public interface UserDaoImpl{
    public User queryUser();
}
委托类:(相当于厂商,需要代理解决判空的问题)
public class UserDao implements UserDaoImpl{
    public User queryUser(){
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        String sql = "select * from user where uname = ? and password = ?";
        User exitUser = qr.query(sql, new BeanHandler<User>(User.class),user.getUname(),user.getPassword());
        return exitUser;
    }
}
代理类:(代理人,处理了判断查询结果是否为空)
public UserDaoProxy implements UserDaoImpl{
    private UserDaoImpl obj;//拥有实现这个接口子类对象的引用   
    public UserDaoProxy (Object obj){
        this.obj = obj; 
    }
    public User queryUser(){
        User user = obj.queryUser();
        //调用这个方法之后,我们可以检查是否有结果
        if(null != user){
            return user;
        }else{
            System.out.println("没有查询到结果");
        }
    }
}
客户(测试):
public class DoMain{
    @Test
    public void test(){
        产生代理对象,传入的为一个userdao的对象,
        UserDaoImpl imp = new UserDaoProxy(new UserDao());
        User user = imp.queryUser();
        System.out.println(user.toString());
    }
}

那么,动态代理与静态代理的区别就是:动态代理并没有代理类的.java文件编写,而是通过Proxy提供的newProxyInstance()这个方法来实现的。
具体实现demo如下:

客户:
创建动态代理的核心方法:
    Proxy.newProxyInstance(①类加载器对象,②类实现的所有接口,③代理处理器InvocationHandler)
    代理处理器InvocationHandler接口,这里通过匿名内部类实现,因为它只提供了一个抽象方法。
    这个处理器主要处理增强的方法的业务实现。这里就实现了对查询结果判空的处理
public class DoMain{
    @Test
    public void test(){
        //产生一个动态代理类对象
        UserDaoImpl proxy = (UserDaoImpl)Proxy.newProxyInstance(UserDaoImpl.class.getClassLoader(),
            UserDaoImpl.class.getInterfaces(),new InvocationHandler(){
            @Override
            Object表示的是委托类的对象,method表示的是委托类中的方法,args参数表示执行此方法需要的参数
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {         
                User result = (User) method.invoke(proxy, args);
                if(null != result){
                    return result;
                }
                return null;
            }
        });
        通过代理对象调用方法。
        User user = proxy.queryUser();
    }
}
具体实现如图:

这里写图片描述

关于使用过滤器结合动态代理完成对请求中文乱码的处理现在就变得容易多了。代码如下:

使用动态代理完成输入中文乱码问题
 *  JDK中的动态代理:Proxy
 *      Proxy.newProxyInstance(ClassLoader,实现的所有接口,对象.getClass().getInterfaces,InvocationHandler);
 *      InvocationHandler接口,它是JDK Proxy实现动态代理的核心,可以理解为一个中介,用于执行委托类的方法
 *      委托类:被增强的类HttpServletRequest 的request对象
 *      代理类:通过newProxyInstance产生的动态代理
 *      中介类:InvocationHandler接口的实现类,执行代理类中的getParameter,进而执行委托类中的getParameter
 *  使用动态代理的条件:
 *  被代理的类需要实现接口,例如:GenericEncodingType 实现Filter接口
@WebFilter("/*")
public class GenericEncodingType implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {
        //
        HttpServletRequest request = (HttpServletRequest)req;
        //使用匿名内部类创建一个动态代理对象
        HttpServletRequest StrongReq = (HttpServletRequest)Proxy.newProxyInstance(request.getClass().getClassLoader(), 
                request.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //method为getParameter时
                        String type = request.getMethod();
                        if("getParameter".equals(method)){
                            if("get".equalsIgnoreCase(type)){
                                String result = (String)method.invoke(request, response);
                                return new String(result.getBytes("ISO-8859-1"),"UTF-8");
                            }else if("post".equalsIgnoreCase(type)){
                                request.setCharacterEncoding("UTF-8");
                            }
                        }
                        return method.invoke(request, response);
                    }
                });
        filterChain.doFilter(StrongReq, response);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值