JAVA HTTP反向代理實(shí)現(xiàn)過(guò)程詳解
反向代理(Reverse Proxy)方式是指以代理服務(wù)器來(lái)接受internet上的連接請(qǐng)求,然后將請(qǐng)求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器,并將從服務(wù)器上得到的結(jié)果返回給internet上請(qǐng)求連接的客戶端,此時(shí)代理服務(wù)器對(duì)外就表現(xiàn)為一個(gè)反向代理服務(wù)器。
簡(jiǎn)單來(lái)說(shuō),你的反向代理服務(wù)器會(huì)接收請(qǐng)求,但其自身不處理該請(qǐng)求,而是對(duì)請(qǐng)求經(jīng)過(guò)一些處理,例如添加日志、緩存、身份驗(yàn)證等服務(wù),然后再將請(qǐng)求轉(zhuǎn)發(fā)到相應(yīng)的應(yīng)用服務(wù)器中進(jìn)行處理,最后將處理結(jié)果返回。
我目前的需求是,A應(yīng)用需要訪問(wèn)B應(yīng)用的報(bào)表頁(yè)面,B應(yīng)用沒(méi)有源碼,要求自動(dòng)處理B應(yīng)用的登錄權(quán)限。避免用戶重復(fù)登錄。
1. 引入相關(guān)依賴
<dependency> <groupId>org.mitre.dsmiley.httpproxy</groupId> <artifactId>smiley-http-proxy-servlet</artifactId> <version>1.11</version> </dependency>
這個(gè)jar包,只有兩個(gè)類,其中核心的就是 ProxyServlet,
作者重寫了HttpServlet的相關(guān)方法。他復(fù)制了新的request為proxyRequest,
然后替換了地址和相關(guān)屬性,并使用HttpClient將proxyRequest發(fā)送出去,
然后將接收到的proxyResponse的內(nèi)容再?gòu)?fù)制給 HttpResponse 。
相當(dāng)于中轉(zhuǎn)站。具體請(qǐng)看源碼。
https://github.com/mitre/HTTP-Proxy-Servlet
2.spring使用:
2.1 application.yml增加代理參數(shù)配置
# 設(shè)置代理 proxy: servlet_url: /webappB/* target_url: https://webappB_HOST_IP:8001/webappB其他demo # servlet_url: /proxybaidu/* # target_url: https://www.baidu.com
此處有玄機(jī):
為什么源url和目標(biāo)url根路徑要一致(都為/webappB/)呢?
這是因?yàn)椋?target_url頁(yè)面里不止文本顯示,還有其他資源的調(diào)用,比如圖片,比如里面的js又調(diào)用了其他url.
這樣的話,假如 target頁(yè)面里某個(gè)圖片的url是相對(duì)路徑 img/test.jpg;
你的頁(yè)面上圖的 /webappC/image/test.jpg; 這樣host換了以后是找不到圖片地址的。
當(dāng)然你也可以改下proxyServlet的源碼,讓它換成正確的url地址。如果不想改源碼的話,那還是一致的比較好。少麻煩。
2.2 注冊(cè)servlet.
@Configuration
public class ProxyServletConfiguration {
/**
* 讀取配置文件中路由設(shè)置
*/
@Value("${proxy.servlet_url}")
private String servlet_url;
/**
* 讀取配置中代理目標(biāo)地址
*/
@Value("${proxy.target_url}")
private String target_url;
@Bean
public Servlet createProxyServlet() {
/** 創(chuàng)建新的ProxyServlet */
return new ProxyServlet();
}
@Bean
public ServletRegistrationBean proxyServletRegistration() {
ServletRegistrationBean registrationBean = new ServletRegistrationBean(createProxyServlet(), servlet_url);
//設(shè)置網(wǎng)址以及參數(shù)
Map<String, String> params = ImmutableMap.of("targetUri", target_url, "log", "true");
registrationBean.setInitParameters(params);
return registrationBean;
}
}
2.3測(cè)試。ok.
localhost:8080/proxybaidu/
2.4. 當(dāng)然你也可以重新寫個(gè)類,MyProxyServlet繼承ProxyServlet.
重新其中的 execute方法。添加相關(guān)的功能。日志,權(quán)限登錄等。
@Override
protected HttpResponse (HttpServletRequest servletRequest, HttpServletResponse servletResponse,
HttpRequest proxyRequest) throws IOException { //設(shè)置header里的授權(quán)信息
proxyRequest.setHeader("Authorization", "Basic " + getWebappBLoginAuth());
HttpResponse response = super.doExecute(servletRequest, servletResponse, proxyRequest);
// 設(shè)置跨域,暫時(shí)不用。
// 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 后記
這個(gè)ProxyServlet 跟 nginx看著基本功能一樣了,都可以反向代理了。
不過(guò)擴(kuò)展功能和IO性能肯定跟nginx沒(méi)法比。但是這個(gè)是用java語(yǔ)言寫的。
方便二次開發(fā)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用java.nio.file?庫(kù)優(yōu)雅的操作文件詳解
這篇文章主要介紹了使用java.nio.file?庫(kù)優(yōu)雅的操作文件詳解,需要的朋友可以參考下2023-05-05
關(guān)于MybatisPlus配置雙數(shù)據(jù)庫(kù)驅(qū)動(dòng)連接數(shù)據(jù)庫(kù)問(wèn)題
這篇文章主要介紹了MybatisPlus配置雙數(shù)據(jù)庫(kù)驅(qū)動(dòng)連接數(shù)據(jù)庫(kù)的具體實(shí)現(xiàn),具體的業(yè)務(wù)邏輯,在service層的類或者方法上面添加@DataSource注解來(lái)指定該業(yè)務(wù)需要用到的數(shù)據(jù)源,需要的朋友可以參考下2022-01-01
JAVA操作MongoDB數(shù)據(jù)庫(kù)實(shí)例教程
MongoDB是一個(gè)文檔型數(shù)據(jù)庫(kù),是NOSQL家族中最重要的成員之一,下面這篇文章主要給大家介紹了關(guān)于JAVA操作MongoDB數(shù)據(jù)庫(kù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05
Java時(shí)區(qū)轉(zhuǎn)換實(shí)例代碼解析
這篇文章主要介紹了Java時(shí)區(qū)轉(zhuǎn)換實(shí)例代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
基于Redisson實(shí)現(xiàn)注解式分布式鎖的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何基于Redisson實(shí)現(xiàn)注解式分布式鎖,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,需要的可以了解一下2023-07-07
Java中生成不重復(fù)隨機(jī)數(shù)的四種方法舉例詳解
在Java編程中獲取隨機(jī)數(shù)是常見的需求,這篇文章主要介紹了Java中生成不重復(fù)隨機(jī)數(shù)的四種方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-04-04

