动态代理-统一编码
静态代理书写步骤:
1.要求被装饰者和装饰者实现同一个接口或者继承同一个类
2.在装饰者中要有被装饰者的引用
3.对需要加强的方法进行加强
4.对不需要加强的方法调用原来的方法
动态代理:
在项目运行的时候才创建一个代理对象,对方法进行增强(控制)
方式1:
jdk中Proxy类,前提:实现接口
方式2:
spring中cglib,前提:继承类
动态的在内存中创建一个代理对象
Object Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
参数说明:
ClassLoader:代理对象类加载器 一般我们使用的是被代理对象的类加载器
Class[]:代理对象需要实现接口 一般我们使用的是被搭理对象所实现的所有接口
InvocationHandler:执行处理类.在这里面对方法进行加强
invocationHandler中只有一个方法
Object invoke(Object proxy, Method method, Object[] args)
参数说明:
proxy:代理对象
method:当前执行的方法
args:当前方法执行的时候所需要的参数
返回值:就是当前method对象执行的返回值
//
步骤分析:
过滤器
doFilter(Request request,Response response)
将代理request传递过去
doFilter(Request requestPrxoy,Response response)
---------------------------------------------------------------------------------------------------
package com.feizhu.web.c_proxy;
public interface Car {
void run();
void stop();
}
---------------------------------------------------------------------------------------------------
package com.feizhu.web.c_proxy;
public class QQ implements Car{
@Override
public void run() {
System.out.println("qq在跑");
}
@Override
public void stop() {
System.out.println("qq刹车");
}
}
----------------------------------------------------------------------------------------------------
package com.feizhu.web.c_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TT {
public static void main(String[] args) {
final QQ qq = new QQ();
// qq.run();
// qq.stop();
// 创建代理对象
Car qqProxy = (Car) Proxy.newProxyInstance(QQ.class.getClassLoader(), new Class[] { Car.class },
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// System.out.println("哈哈");
// System.out.println(method.getName());
// obj就是代理对象
// Object obj= method.invoke(qq, args);
// return obj;
// 对run方法进行加强
/*
* System.out.println("加上电池"); Object obj= method.invoke(qq, args);
* System.out.println("5秒破百");
*
* return obj;
*/
// 只对run方法进行加强
if ("run".equals(method.getName())) {
System.out.println("加上电池");
Object obj = method.invoke(qq, args);
System.out.println("5秒破百");
return obj;
}
return method.invoke(qq, args);
}
});
qqProxy.run();
qqProxy.stop();
}
}
---------------------------------------------------------------------------------------------------
package com.feizhu.a_proxy.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;
import javax.servlet.http.HttpServletResponse;
@WebFilter(urlPatterns="/*")
public class EncodingFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
//强转
HttpServletRequest request =(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse) resp;
//创建代理对象
HttpServletRequest requestProxy=(HttpServletRequest) Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(),request.getClass().getInterfaces(),new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("getParameter".equals(method.getName())) {
//获取请求方式
String m= request.getMethod();
if("get".equalsIgnoreCase(m)) {
String s=(String) method.invoke(request, args); //相当于 request.getParameter(args);
return new String(s.getBytes("iso8859-1"),"utf-8");
}else if("post".equalsIgnoreCase(m)) {
request.setCharacterEncoding("utf-8");
return method.invoke(request, args);
}
}
//不需要加强的方法
return method.invoke(request, args);
}
});
//放行
chain.doFilter(requestProxy, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
---------------------------------------------------------------------------------------------------
package com.feizhu.a_proxy.encoding;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String memo = request.getParameter("memo");
System.out.println(username);
System.out.println(memo);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}