版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第JavaHttp多次請(qǐng)求復(fù)用同一連接示例詳解目錄概述復(fù)用的基本條件理論基礎(chǔ)現(xiàn)實(shí)基礎(chǔ)獲取HTTP資源常見(jiàn)方式Transfer-Encoding簡(jiǎn)略實(shí)現(xiàn)
概述
注:
本文乃是最簡(jiǎn)單的實(shí)現(xiàn),真實(shí)場(chǎng)景要復(fù)雜麻煩的多旨在闡述清晰多次HTTP請(qǐng)求復(fù)用一個(gè)連接的底層邏輯
早在HTTP/1.0時(shí)代,每次HTTP請(qǐng)求都要?jiǎng)?chuàng)建一個(gè)連接,而創(chuàng)建連接的過(guò)程需要消耗資源和時(shí)間,代價(jià)相對(duì)昂貴,為了減少資源消耗,縮短響應(yīng)時(shí)間,就需要重用連接。在后來(lái)的HTTP/1.1中,引入了連接復(fù)用的機(jī)制,HttpHeader中加入Connection:keep-alive來(lái)告訴對(duì)方這個(gè)請(qǐng)求響應(yīng)完成后先不忙關(guān)閉,這也是本篇文章的由來(lái)。
復(fù)用的基本條件
理論基礎(chǔ)
OSI是OpenSystemInterconnection的縮寫(xiě),意為開(kāi)放式系統(tǒng)互聯(lián)。國(guó)際標(biāo)準(zhǔn)化組織(ISO)制定了OSI模型,該模型定義了不同計(jì)算機(jī)互聯(lián)的標(biāo)準(zhǔn),是設(shè)計(jì)和描述計(jì)算機(jī)網(wǎng)絡(luò)通信的基本框架。也就是如下七層模型:
當(dāng)然也有大家熟知的五層模型,也就是把會(huì)話層、表示層、應(yīng)用層合稱(chēng)為應(yīng)用層。耳熟能詳?shù)腡CP、UDP屬于數(shù)量稀少的傳輸層協(xié)議。在這之上的應(yīng)用層協(xié)議百花齊放諸如:HTTP、SMTR、FTP......,然后很多中間件也自定義了通訊協(xié)議,比如Dubbo、Mysql。
讀到這里大家可能就已經(jīng)清醒的意識(shí)到,即使同屬應(yīng)用層的協(xié)議,是否支持長(zhǎng)連接也不盡相同。筆者想要傳達(dá)的一個(gè)認(rèn)知:之所以能支持長(zhǎng)連接,那是因?yàn)門(mén)CP經(jīng)歷三次握手建立連接之后,如果不出現(xiàn)其他意外是可以保證連接狀態(tài)的。也就是說(shuō)應(yīng)用層協(xié)議是否屬于長(zhǎng)連接僅僅取決于成功建立TCP,發(fā)送一個(gè)請(qǐng)求之后,對(duì)該連接的處理策略:
如早期的HTTP每次發(fā)送請(qǐng)求,Server端回復(fù)完畢之后直接關(guān)閉則是短連接如Mysql處理完一條SQL請(qǐng)求,然后繼續(xù)執(zhí)行下一個(gè)則是長(zhǎng)連接
這其實(shí)就是我們的理論基礎(chǔ),HTTP有希望支持長(zhǎng)連接的前提是TCP本身就是長(zhǎng)連接。
現(xiàn)實(shí)基礎(chǔ)
HTTP協(xié)議并非魔法,不是說(shuō)新增一條規(guī)范,也不是簡(jiǎn)簡(jiǎn)單單的Header中加入Connection:keep-alive就能立馬支持長(zhǎng)連接了。想要達(dá)到這個(gè)目的需要Client、Server端共同努力。
客戶(hù)端譬如Chrome瀏覽器,服務(wù)端譬如阿里OSS,像這樣兩端都支持了新的規(guī)范,HTTP才能快樂(lè)的成為長(zhǎng)連接陣營(yíng)中的一員。
獲取HTTP資源常見(jiàn)方式
因?yàn)镴DK提供了相關(guān)工具、且平臺(tái)相關(guān)的第三方包也足夠優(yōu)秀,所以Java獲取HTTP資源并非難事。
@Slf4j
publicclassSinaPicDownload{
/*微博上某個(gè)畫(huà)師的作品*/
staticfinalStringHTTP_URL="/mw2000/006jQ3i8ly1h5k50zujydj35k0334kjo.jpg";
/*下載之后放在顏如玉電腦的io文件下*/
staticfinalStringLOCAL="/Users/admin/io/靈魂蓮華-皎月.jpeg";
publicstaticvoidmain(String[]args){
try(
InputStreamin=newURL(HTTP_URL).openStream();
FileOutputStreamout=newFileOutputStream(LOCAL)
byte[]buffer=newbyte[10242];
intread;
while((read=in.read(buffer))-1){
out.write(buffer,0,read);
out.flush();
catch(Throwablee){
log.error("獲取HTTP資源失敗:",e);
配合Java7之后提供的try-with-resources語(yǔ)法糖,你甚至僅僅只需要不到二十行的代碼就可以輕而易舉的達(dá)到目的,但是缺點(diǎn)也顯而易見(jiàn),通過(guò)這種方法每次只能獲取一個(gè)資源,用完之后只能完畢。我當(dāng)時(shí)就在想,Java怎么實(shí)現(xiàn)一次連接多次請(qǐng)求呢?
Transfer-Encoding
筆者在上文提到的理論基礎(chǔ)上推測(cè)到肯定可以使用Java提供的Socket建立TCP連接,關(guān)鍵問(wèn)題是怎么跟Server端描述HTTP請(qǐng)求呢?
類(lèi)比到現(xiàn)實(shí)生活中,兩者能順暢交流必然要求雙方都可以聽(tīng)懂對(duì)方的語(yǔ)言。那HTTP有沒(méi)有一種Client、Server都能解析的規(guī)范呢,HTTPTransfer-Encoding正是在這種背景下應(yīng)運(yùn)而生。通俗的來(lái)講Transfer-Encoding就是一種雙方都約定好的格式,我按照這個(gè)格式Encoding,你按照這個(gè)格式Decoding,ta大概長(zhǎng)這個(gè)樣子:
可想而知?jiǎng)倓偒@取那張圖片資源的是時(shí)候,我們肯定是這么跟新浪微博服務(wù)端說(shuō)的:
聲明:
真實(shí)的RequestLine與圖中一致Header其實(shí)復(fù)雜很多,配圖做了簡(jiǎn)化該請(qǐng)求Body為空,圖中略過(guò)
簡(jiǎn)略實(shí)現(xiàn)
先聲明一些常量,以備后用
@Slf4j
publicclassReusableHttp{
/*顏如玉公司的OSS服務(wù)域名*/
staticfinalStringHOST="****.";
staticfinalintPORT=80;
/*顏如玉在OSS上放置的幾個(gè)資源*/
staticfinalString[]URLS=newString[]{
"/context/reusable/gtyj.text",
"/context/reusable/tlyxqch.text",
"/context/reusable/yj.text",
"/context/reusable/ls.text"
/*CR='\r';LF='\n'*/
staticfinalbyte[]CRLF=newbyte[]{Chars.CR,Chars.LF};
staticfinalStringLOCAL_PATH="/Users/admin/io/";
建立TCP連接,然后獲得輸出,輸入流
publicstaticvoidmain(String[]args){
try{
try(
Socketsocket=newSocket(HOST,PORT);
OutputStreamout=socket.getOutputStream();
InputStreamin=socket.getInputStream()
/*復(fù)用連接,獲取資源*/
reusable(out,in);
catch(IOExceptione){
log.error("請(qǐng)求出現(xiàn)異常",e);
寫(xiě)出RequestLine
/**
*WriteRequestLine
*RequestLineencoding規(guī)范
***********************************************
**method*sp*URL*sp*version*cr*lf*
***********************************************
staticvoidwriteRequestLine(OutputStreamout,Stringurl)throwsIOException{
/*注意空格一定要按照規(guī)定來(lái)擺放*/
out.write(("GET"+url+"HTTP/1.1").getBytes());
/*最后再寫(xiě)入一個(gè)回車(chē)、換行符表示RequestLine結(jié)束*/
out.write(CRLF);
寫(xiě)出RequestHeader
/**
*WriteRequestHeader
*HeaderLineencoding規(guī)范
********************************************
**headerfieldname*:*value*cr*lf*
********************************************
*....
********************************************
**headerfieldname*:*value*cr*lf*
********************************************
*...
************
**cr*lf*
************
****************
**EntityBody*
****************
staticvoidwriteHeaderLine(OutputStreamout)throwsIOException{
out.write("Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9".getBytes());
out.write(CRLF);
out.write("Accept-Encoding:gzip,deflate".getBytes());
out.write(CRLF);
out.write("Accept-Language:zh-CN,zh;q=0.9".getBytes());
out.write(CRLF);
out.write("Connection:keep-alive".getBytes());
out.write(CRLF);
out.write("Host:".getBytes());
out.write(CRLF);
/*最后再寫(xiě)入一個(gè)回車(chē)、換行符表示RequestHeader結(jié)束*/
out.write(CRLF);
因?yàn)槭呛?jiǎn)單的請(qǐng)求,所以直接省略RequestBody。發(fā)出如上報(bào)文后,Server端會(huì)解析請(qǐng)求,然后回復(fù)。
/**
*1.向Server端寫(xiě)出請(qǐng)求
*2.接受Server端回復(fù)
*3.寫(xiě)到顏如玉本地機(jī)器的io文件夾下
*@paramout往Server端寫(xiě)出流
*@paraminServer端往Client端寫(xiě)入流
staticvoidreusable(OutputStreamout,InputStreamin)throwsIOException{
for(inti=0,s=URLS.length;ii++){
writeRequestLine(out,URLS[i]);
writeHeaderLine(out);
out.flush();
byte[]bytes=newbyte[512];
in.read(bytes);
Stringfile=LOCAL_PATH+i+".te
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 臺(tái)灣情報(bào)機(jī)構(gòu)人員培訓(xùn)制度
- 中學(xué)信息化培訓(xùn)制度匯編
- 證券公司員工培訓(xùn)制度
- 德育隊(duì)伍培訓(xùn)管理制度
- 食品企業(yè)內(nèi)部培訓(xùn)制度
- 鄉(xiāng)村醫(yī)生培訓(xùn)工作制度
- 學(xué)校培訓(xùn)檔案工作制度匯編
- 國(guó)培計(jì)劃學(xué)校培訓(xùn)制度
- 護(hù)理三基培訓(xùn)獎(jiǎng)懲制度
- 單位級(jí)教育培訓(xùn)制度
- GB/T 17213.4-2015工業(yè)過(guò)程控制閥第4部分:檢驗(yàn)和例行試驗(yàn)
- FZ/T 73009-2021山羊絨針織品
- JJF 1069-2012 法定計(jì)量檢定機(jī)構(gòu)考核規(guī)范(培訓(xùn)講稿)
- GB∕T 5900.2-2022 機(jī)床 主軸端部與卡盤(pán)連接尺寸 第2部分:凸輪鎖緊型
- 2011-2015廣汽豐田凱美瑞維修手冊(cè)wdl
- DFMEA編制作業(yè)指導(dǎo)書(shū)新版
- KTronics籃輸送式洗碗碟機(jī)操作手冊(cè)
- DB35∕T 1844-2019 高速公路邊坡工程監(jiān)測(cè)技術(shù)規(guī)程
- 城市管理綜合執(zhí)法局城管執(zhí)法與執(zhí)法程序PPT模板
- 閥門(mén)基礎(chǔ)知識(shí)上
- 第二章注射成型工藝與模具結(jié)構(gòu)
評(píng)論
0/150
提交評(píng)論