Apache HttpCore 學習


最近有點時間,想學習下 http 的規范,理論和實踐結合學習是最有效果的學習方法,如是結合 Apache httpcomponets 的源碼,嘗試理解http的設計思想,但是整個學習下來,在代碼設計規划上也學習到不少東西,這要得益於httpcore,httpclient優秀的源碼.

http協議所描述的可以用一句話概括:點對點的消息交換(一端向另一端發起請求(request),接收端處理請求並返回消息(response)). 不管是http請求還是http響應,我們都把它當做http消息(message)。

                                               (picture 1)

Apache HttpCore 中完全按照rfc文檔定義對象接口關系。HttpRequestHttpResponse 都擴展繼承自 HttpMessage接口。picture 1 中,接口 HttpEntityClosingRequest 擴展了 HttpReqeust 接口,那HttpEntityClosingRequest 是在rfc文檔中對應怎樣的描述?

7 Entity
Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or
response status code. An entity consists of entity-header fields and an entity-body, although some responses will only
include the entity-headers.
In this section, both sender and recipient refer to either the client or the server, depending on who sends and who
receives the entity.

請求和返回消息都可以附帶一個消息實體傳輸,如果請求方法和返回碼都沒有限制的話。消息實體可以包括實體頭和實體內容,盡管有些返回消息只包括實體頭。

我在最開始看文檔時,始終對entiy的概念模模糊糊,理解不透,通過google一些文章和反復看文檔才有些眉目。其實我們可以這么理解entiy:對於消息請求時,例於post請求時,提交的表單內容即可看成entity消息實體;對於消息返回時,我們接收到<html>...</html>標記文檔即可看做entity實體。所以說一個消息(不管是請求還是響應消息),里面除了消息頭(header),就是消息實體(entity),當然目前為止,你可以這樣理解,后面我們會指出這里有些問題。相關參考

                                                    (picture 2)

消息實體在Apache HttpCore中相關接口定義如圖picture 2,可以看到有各種版本的entiy實現,不同的實現區別僅在對entiy的表現存在形式不同而也:
ByteArrayEntiy          : byte數組實現
FileEntiy                   : 本地文件實現
InputStreamEntiy       : io流文件實現
HttpEntityWrapper     : 對別的entity進行包裝,添加新功能,利用decorator模式
BufferedHttpEntity     : 繼承擴展HttpEntityWrapper,實現可緩沖的entity

   這些entity接照其內容存在地方形式分為如下類別:

  • streamed: The content is received from a stream, or generated on the fly. In particular, this category includes entities being received from a connection. Streamed entities are generally not repeatable.
  • self-contained: The content is in memory or obtained by means that are independent from a connection or other entity. Self-contained entities are generally repeatable.
  • wrapping: The content is obtained from another entity.
  1. streamed : BaseHttpEntity,InputStreamEntity
  2. self-contained : FileEntity,BufferedHttpEntity
  3. wrapping : HttpEntityWrapper

這里比較有意思的是BufferedHttpEntity,它既是wrapping類別,也屬於self-contained類別。正是因為它是wrapping類別的,所以它會包裝其它的entity,如果被包裝的entity本身是self-contained的,則直接調用它的方法,如果被包裝的entity是streamed類型的,則會把它緩存起來,形成self-contained形式。

 ----------------------------------------------------------------------

Request Method(請求方法)

  • Options
  • Get
  • Head
  • Post
  • Put
  • Delete
  • Trace
  • Connect

這些請求方法中,我們最熟悉是Get和Post這兩種方法,其它的基本上沒有用到。不過由於最近開放平台的興起,開發人員慢慢的要接觸和熟悉起這些方法來。其實從這些方法名的語義上,便可直觀的了解這些方法所要表達的行為方式。Get:得到資源數據,Delete刪除資源數據......。關於其中更高層的思想境界,值得一看的是Roy Fielding的論文

這里最容易讓人不理解的是Put和Post的區別到底是什么。它們都是通過指定的Uri來提交帶有entity的消息請求(request),並要求服務端(server)接收並處理這些請求。但是Post方法指的是廣義的處理方式,何為廣義上的處理呢,引用rfc文檔:

· Annotation of existing resources;
· Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles;
· Providing a block of data, such as the result of submitting a form, to a data-handling process;
· Extending a database through an append operation.

引用內容大概是說Post方法是對存在的資源進行注解;提交生成一個內部通告,新聞組,郵件列表;提交一些表單數據進行處理;擴展數據庫。
而Put方法具有更狹義的語義:提交一個附帶entity的請求消息(request)到指定的Uri,在該Uri上保存entity,如果該Uri之前保存過entity,則最新的entity覆蓋之。
所以說Post的操作語義范圍較Put更廣,Post指所有的處理資源方式,而Put則是注重Uri和Entity的對應關系。

舉個形象的例子:

POST/book/add           這里是添加一本書,每Post一次則新增一本書

PUT   :  /book/add/1         這里添加ID為1的一本書,如果服務端發現此id=1的書已存在,則覆蓋之,相當於edit操作

   -----------------------------------------------------------------

 消息頭(Header)

消息頭可以看成是消息的元數據描述對象,它是對請求消息(request),響應消息(response),消息實體(entity)的元描述,比如請求消息頭Accept就是指定請求客戶端可以理解哪些媒體類型,Content-Length頭指定entity的大小長度。

                                                                                                           (picture 3)

 

------------------------------------------------------------

下面把Apache HttpCore設計得比較好的地方拿出來分析下:


HttpParams


在Http各組件運行中,都要用到各種運行時的參數

(picture 4)

針對Connection(網絡連接資源,如Socket)進行“池”管理。

 (picture 5)

 主要是對URI中相同的Host建立的Socket連接實現reuseable化,提高效率和優化性能,滿足Http1.1中的Connection頭描述(值為keep-alive時不關閉每個當前連接,以供下次請求使用)

 AOP架構模式,攔截處理request和response消息的各種頭,內容體處理

 

 

 ------------------------------------------------------------------------------

總結

這篇文章只是根據rfc規范和Apache HttpCore中的架構設計相互參考學習后的一些筆記,圖中列出的UML類圖也只是從抽象層面理解http的設計。后續會繼續從這些接口實現細節上,抽出一部分值得分享,記錄的內容寫下來。由於這篇文章只是學習筆記,如果您看起來比較不知所然,建議詳細學習文中的給出的學習鏈接。

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM