反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的連接請求,然后將請求轉發給內部網絡上的服務器,并將從服務器上得到的結果返回給internet上請求連接的客戶端,此時代理服務器對外就表現為一個反向代理服務器。
簡單來說,你的反向代理服務器會接收請求,但其自身不處理該請求,而是對請求經過一些處理,例如添加日志、緩存、身份驗證等服務,然后再將請求轉發到相應的應用服務器中進行處理,最后將處理結果返回。
我目前的需求是,A應用需要訪問B應用的報表頁面,B應用沒有源碼,要求自動處理B應用的登錄權限。避免用戶重復登錄。
1. 引入相關依賴
1
2
3
4
5
|
< dependency > < groupId >org.mitre.dsmiley.httpproxy</ groupId > < artifactId >smiley-http-proxy-servlet</ artifactId > < version >1.11</ version > </ dependency > |
這個jar包,只有兩個類,其中核心的就是 ProxyServlet,
作者重寫了HttpServlet的相關方法。他復制了新的request為proxyRequest,
然后替換了地址和相關屬性,并使用HttpClient將proxyRequest發送出去,
然后將接收到的proxyResponse的內容再復制給 HttpResponse 。
相當于中轉站。具體請看源碼。
https://github.com/mitre/HTTP-Proxy-Servlet
2.spring使用:
2.1 application.yml增加代理參數配置
1
2
3
4
5
6
|
# 設置代理 proxy: servlet_url: /webappB/ * target_url: https: //webappB_HOST_IP :8001 /webappB 其他demo # servlet_url: /proxybaidu/* # target_url: <a href="https://www.baidu.com" rel="external nofollow">https://www.baidu.com</a> |
此處有玄機:
為什么源url和目標url根路徑要一致(都為/webappB/)呢?
這是因為: target_url頁面里不止文本顯示,還有其他資源的調用,比如圖片,比如里面的js又調用了其他url.
這樣的話,假如 target頁面里某個圖片的url是相對路徑 img/test.jpg;
你的頁面上圖的 /webappC/image/test.jpg; 這樣host換了以后是找不到圖片地址的。
當然你也可以改下proxyServlet的源碼,讓它換成正確的url地址。如果不想改源碼的話,那還是一致的比較好。少麻煩。
2.2 注冊servlet.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
@Configuration public class ProxyServletConfiguration { /** * 讀取配置文件中路由設置 */ @Value ( "${proxy.servlet_url}" ) private String servlet_url; /** * 讀取配置中代理目標地址 */ @Value ( "${proxy.target_url}" ) private String target_url; @Bean public Servlet createProxyServlet() { /** 創建新的ProxyServlet */ return new ProxyServlet(); } @Bean public ServletRegistrationBean proxyServletRegistration() { ServletRegistrationBean registrationBean = new ServletRegistrationBean(createProxyServlet(), servlet_url); //設置網址以及參數 Map<String, String> params = ImmutableMap.of( "targetUri" , target_url, "log" , "true" ); registrationBean.setInitParameters(params); return registrationBean; } } |
2.3測試。ok.
localhost:8080/proxybaidu/
2.4. 當然你也可以重新寫個類,MyProxyServlet繼承ProxyServlet.
重新其中的 execute方法。添加相關的功能。日志,權限登錄等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@Override protected HttpResponse (HttpServletRequest servletRequest, HttpServletResponse servletResponse, HttpRequest proxyRequest) throws IOException { //設置header里的授權信息 proxyRequest.setHeader( "Authorization" , "Basic " + getWebappBLoginAuth()); HttpResponse response = super .doExecute(servletRequest, servletResponse, proxyRequest); // 設置跨域,暫時不用。 // String origin = servletRequest.getHeader("origin"); // response.setHeader("Access-Control-Allow-Origin", origin); // response.setHeader("Access-Control-Allow-Credentials", "true"); // response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); // response.setHeader("Access-Control-Allow-Headers", // "Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin" + // ",User-Agent,X-Mx-ReqToken,X-Requested-With"); return response; } |
2.5 后記
這個ProxyServlet 跟 nginx看著基本功能一樣了,都可以反向代理了。
不過擴展功能和IO性能肯定跟nginx沒法比。但是這個是用java語言寫的。
方便二次開發。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://www.cnblogs.com/java2sap/p/13200636.html