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
}
}
運行截圖
思考代理模式
代理模式的本質: 控制對象訪問。
代理模式通過代理目標對象,把代理對象插入到客戶和目標對象之間,從而爲客戶和目標對象引入一定的間接性。正是這個間接性,給了代理對象很多的活動空間。代理對象可以在調用具體的目標對象前後,附加很多操作,從而實現新的功能或是擴展目標對象的功能。更狠的是,代理對象還可以不去創建和調用目標對象,也就是說,目標對象被完全代理掉了,或是被替換掉了。
引用自《研磨設計模式》