黑马程序员技术交流社区

标题: 【济南中心】JavaEE就业班同步笔记第一阶段:动态代理 [打印本页]

作者: 小鲁哥哥    时间: 2017-3-26 20:39
标题: 【济南中心】JavaEE就业班同步笔记第一阶段:动态代理
【济南中心】JavaEE就业班同步笔记第一阶段:
JavaWeb之基础加强--动态代理

1. 案例三:使用动态代理的方式统一网站的字符集编码
1.1 需求:
在一个表单中分别使用get和post提交到Servlet中,在Servlet中直接调用getParameter方法解决中文乱码的问题!!!
1.2 分析:
1.2.1 技术分析:
【动态代理】
增强一个类中的某个方法.对程序进行扩展.Spring框架中AOP.
什么是代理:
【入门案例】
[Java] 纯文本查看 复制代码
class MyInvocationHandler implements InvocationHandler{
    private Waiter waiter;
    public MyInvocationHandler(Waiter waiter) {
        this.waiter = waiter;
    }
    @Override
    // 执行目标对象的任何一个方法 都相当于执行了invoke方法.
    /**
     * proxy:产生代理对象.
     * method:代表正在调用的方法.
     * Object[]:在调用的方法的参数.
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // System.out.println("aaaaa");
        // System.out.println(method.getName());
        if("server".equals(method.getName())){
            // 增强server.
            System.out.println("微笑...");
            return method.invoke(waiter, args);
        }else{
            // 不增强:
            return method.invoke(waiter, args);
        }
        // return null;
    }
}

1.3 代码实现:
[Java] 纯文本查看 复制代码
package com.itheima.encoding;
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.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

@WebFilter(urlPatterns="/*")
public class GenericCharacterEncodingFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {     
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        final HttpServletRequest req = (HttpServletRequest) request;   
        // 对req产生代理对象:
        HttpServletRequest myReq = (HttpServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(),req.getClass().getInterfaces(), new InvocationHandler() {
           
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 增强getParameter:
                if("getParameter".equals(method.getName())){
                    // 增强.
                    // 根据请求方式:
                    String type = req.getMethod();
                    if("get".equalsIgnoreCase(type)){
                        // 调用原有的getParameter:
                        String value = (String)method.invoke(req, args);
                        String s = new String(value.getBytes("ISO-8859-1"),"UTF-8");
                        return s;
                       
                    }else if("post".equalsIgnoreCase(type)){
                        req.setCharacterEncoding("UTF-8");
                        return method.invoke(req, args);
                    }
                  
                }
                // 不增强:
                return method.invoke(req, args);   
            }
        });     
        chain.doFilter(myReq, response);
    }
    @Override
    public void destroy() {     
    }
}

1.4 总结:
1.4.1 【类的加载器:了解】
类加载器就是将class文件加载到内存.
JDK中提供的类加载器:
* 引导/系统类加载器    :Java\jre7\lib\rt.jar
* 扩展类加载器        :Java\jre7\lib\ext\*.jar
* 应用类加载器        :自定义的类,类路径下的所有class文件.
类的加载器的机制    :全盘委托机制.
引导类加载器
    |
扩展类加载器
    |
应用类加载器
[Java] 纯文本查看 复制代码
class A{
    String s;
}

class文件由应用类加载器获得到,没有加载,向上一层委托向扩展类加载器委托,向上一层进行委托委托给引导类加载器.引导类加载器查看class哪些它负责,将自己负责的这个class进行加载.不是其负责的就向下传递扩展类加载器.扩展类加载器查看是否是其管理的class,如果是加载,不是就再向下到应用类加载器.


作者: zhouxiaoyang    时间: 2017-3-26 20:57
这么赞6666

作者: liujinlong666    时间: 2017-6-1 00:05
谢谢分享!!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2