1.代理模式的定义
为其他对象提供一种代理以控制对这个对象的访问。
代理模式的功能
代理模式是通过创建一个代理对象,然后用这个代理对象去替代真实的对象,而用户直接使用代理对象,并且不会对用户造成什么影响,就跟得到了真实对象一样来使用。
而当客户端操作这个代理对象的时候,实际上功能最终还是会由真实的对象来完成,只不过是通过代理操作的,也就是用户操作代理,代理操作真正的对象。相当于一个中介,而我们可以通过这个中介在中转的时候就有很多花招可以玩,比如,判断一下权限,如果没有足够的权限那就不能跳转,也可以通过代理模式来处理客户端发送给服务器端的中文乱码的问题。
Java中代理模式可以分为静态代理和动态代理
利用动态代理解决客户端与服务器之间的乱码问题
前端页面代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$(function() {
$("#submit1").click(function() {
var username = $("#username1").val();
$.get("ServletDemo", {
username : username
}, function(data, status) {
});
})
})
$(function() {
$("#submit2").click(function() {
var username = $("#username2").val();
$.post("ServletDemo", {
username : username
}, function(data, status) {
});
})
})
</script>
</head>
<body>
<h4>以get方式提交</h4>
<br>
<input type="text" id="username1">
<br>
<input type="submit" id="submit1" value="提交">
<br>
<h4>以post方式提交</h4>
<input type="text" id="username2">
<br>
<input type="submit" id="submit2" value="提交">
<br>
</body>
</html>
Servlet代码
package com.gzgs.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletDemo extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println("username=="+username);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Filter代码
package com.gzgs.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.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class FilterDemo implements Filter {
public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//将req进行强转
final HttpServletRequest request = (HttpServletRequest)req;
HttpServletRequest myreq=(HttpServletRequest)Proxy.newProxyInstance(FilterDemo.class.getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj=null;
if(method.getName().equals("getParameter")) {
//获取本次方法的请求
String md = request.getMethod();
if("get".equalsIgnoreCase(md)) {
//先调用request的getparameter的方法获得参数,在转码
String invoke = (String)method.invoke(request, args);
return new String(invoke.getBytes("iso-8859-1"),"utf-8");
}else {
request.setCharacterEncoding("utf-8");
obj=method.invoke(request, args);
}
}else {
obj=method.invoke(request, args);
}
return obj;
}
});
chain.doFilter(myreq, response);
}
public FilterDemo() {
// TODO Auto-generated constructor stub
}
public void destroy() {
// TODO Auto-generated method stub
}
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
运行截图
思考代理模式
代理模式的本质: 控制对象访问。
代理模式通过代理目标对象,把代理对象插入到客户和目标对象之间,从而为客户和目标对象引入一定的间接性。正是这个间接性,给了代理对象很多的活动空间。代理对象可以在调用具体的目标对象前后,附加很多操作,从而实现新的功能或是扩展目标对象的功能。更狠的是,代理对象还可以不去创建和调用目标对象,也就是说,目标对象被完全代理掉了,或是被替换掉了。
引用自《研磨设计模式》