1. 程式人生 > >Spring框架之spring-web http原始碼完全解析

Spring框架之spring-web http原始碼完全解析

Spring框架之spring-web http原始碼完全解析

        Spring-web是Spring webMVC的基礎,由http、remoting、web三部分組成。

        http:封裝了http協議中的client/server端的request請求/response響應,編解碼,一些格式的轉換(如cbor、Rss、json、xml)。

        remoting:遠端呼叫,包括caucho、httpinvoker、jaxws。caucho公司提出的基於HTTP實現的兩種遠端服務Burlap和hessian。HttpInvoker是spring 框架中基於 HTTP的一個遠端呼叫模型,只能用於Spring框架。jaxws是Sun推出的web services協議棧。

        web:包含了和web相關的accept、bind、client、context、cors、filter、jsf、method、multipart、server、util。

        Spring-web是Spring webMVC的基礎,HTTP用於Web瀏覽器和Web伺服器之間的雙工通訊,所以Spring-web http模組又是Spring-web的基礎,它包含五個模組:

        1、 http 封裝的基礎,如httpHeader、HttpEntity 、HttpMessage 、MediaType 、HttpMethod 、httpStatus、HttpCookie等;

        2、client端的request請求(傳送出去的)及response響應(接收到的);

        3、 server端的request請求(接收到的)及response響應(傳送出去的);

        4、格式的轉換,如json,rss,xml等。

        5、 編/解碼器。

        本文基於version為5.2.4.BUILD-SNAPSHOT的Spring原始碼版本進行分析,主要從HTTP基礎及Spring-web http五個子模組共六部分進行分析。

一、HTTP基礎

(1)HTTP協議:HTTP(Hypertext Transfer Protocol,超文字傳輸協議)是在全球資訊網上進行通訊時所使用的協議方案,基於TCP/IP的應用層協議。HTTP有很多應用,最著名的就是用於Web瀏覽器和Web伺服器之間的雙工通訊。客戶端向伺服器傳送HTTP請求,伺服器在HTTP響應中回送所請求的資料。

(2)MIME型別:因特網上有數千中不同的資料型別,HTTP給每種要通過Web傳輸的物件都打上MIME型別的資料格式標籤。MIME型別是一種文字標記,表示一種主要的物件型別和一個特定的子型別,中間由一條斜槓分隔。如text/html標記HTML 格式的文字文件;由text/plain標記普通的ASCII 文字文件;image/jpeg標記JPEG 格式的圖片。

(3)URL:統一資源定位符。每個伺服器資源都有一個名字,在世界範圍內唯一的標識並定位資訊資源。

(4)HTTP方法:每條HTTP請求報文都包含一個方法,這個方法告訴伺服器要執行什麼動作,比如獲取一個頁面、執行一個閘道器程式或者刪除一個檔案。五種常見的HTTP方法:

        1、GET 從伺服器向客戶端傳送命名資源;

        2、PUT 將來自客戶端的資料儲存到一個命名的伺服器資源中去;

        3、DELETE 從伺服器中刪除命名資源;

        4、POST 將客戶端資料傳送到一個伺服器閘道器應用程式;

        5、HEAD 僅傳送命名資源響應中的HTTP 首部。

(5)狀態碼(HTTP Status Code):每條HTTP響應報文返回時都會攜帶一個狀態碼,是一個三位數字的程式碼,告知客戶端請求是否成功,或者是否需要採取其他動作。

        1xx訊息:這一型別的狀態碼,代表請求已被接受,需要繼續處理。

        2xx成功:這一型別的狀態碼,代表請求已成功被伺服器接收、理解、並接受。

        3xx重定向:這類狀態碼代表需要客戶端採取進一步的操作才能完成請求。

        4xx客戶端錯誤:這類的狀態碼代表了客戶端看起來可能發生了錯誤,妨礙了伺服器的處理。

        5xx伺服器錯誤:表示伺服器無法完成明顯有效的請求。

(6)HTTP報文: HTTP報文是由一行行的簡單字串組成,都是純文字,不是二進位制程式碼,可以方便進行讀寫。分為HTTP請求和響應報文,無其他型別的HTTP報文,請求和響應報文格式很相似,包括起始行、首部欄位、主體3個部分。

        1、起始行:報文的第一行就是起始行,在請求報文中用來說明要做些什麼,在響應報文中說明出現了什麼情況。

        2、首部欄位:起始行後面有零個或多個首部欄位。每個首部欄位都包含一個名字和一個值,為了便於解析,兩者之間用冒號來分隔。首部以一個空行結束。新增一個首部欄位和新增新行一樣簡單。

        3、主體:空行之後就是可選的報文主體了,其中包含了所有型別的資料。請求主體中包括了要傳送給Web 伺服器的資料;響應主體中裝載了要返回給客戶端的資料。起始行和首部都是文字形式且都是結構化的,而主體則不同,主體中可以包含任意的二進位制資料,比如圖片、視訊、音軌、軟體程式,文字等。

(7)請求報文(request message):從客戶端發往伺服器的HTTP報文。

請求報文示例:

        GET/sample.Jsp HTTP/1.1

        Accept:image/gif.image/jpeg,*/*

        Accept-Language:zh-cn

        Connection:Keep-Alive

        Host:localhost

        User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)

        Accept-Encoding:gzip,deflate

         

        username=jinqiao&password=1234

        1、起始行:請求報文的起始行又叫請求行,請求伺服器對資源做一些操作,包含了一個方法和一個請求的URL。這個方法描述了伺服器應該執行的操作,請求URL描述了要對哪個資源執行這個方法。請求行中還包含HTTP 的版本,用來告知伺服器,客戶端使用的是哪種HTTP。上例中“GET”代表請求方法,“/sample.jsp”表示URI,“HTTP/1.1代表協議和協議的版本。

        2、請求頭:跟在起始行後面的就是零個、一個或多個HTTP 首部欄位。包含客戶端的環境及請求正文相關資訊。

        3、請求體:首部欄位和主體之間有一個空行,表示首部欄位結束,接下來是主體。上例請求正文中包含客戶提交的查詢字串資訊.

(8)響應報文(response message):從伺服器發往客戶端的報文。

響應報文示例:

        HTTP/1.0 200 OK

        Date: Sun, o1 Oct 2000 23:25:17 GMT

        Server: Apache/1.3.11 BSafe-SSL/1.38 (Unix)

        Last-modified: Tue, 04 Jul 2000 09:46:21 GMT

        Content-length: 403

        Content-type: text/html

           

        Hi! I’m a message!

        1、起始行:響應報文的起始行又稱響應行,包含了響應報文使用的HTTP 版本、數字狀態碼,以及描述操作狀態的文字形式的原因短語。上例中:HTTP 版本為HTTP/1.0,狀態碼為200(表示成功),原因短語為OK,表示文件已經被成功返回了。

        2、響應頭:跟在起始行後面的就是零個、一個或多個HTTP 首部欄位。

        3、響應體:第三部分是可選的實體主體部分。實體的主體是HTTP 報文的負荷,就是HTTP 要傳輸的內容。可以承載多種型別的數字資料,如圖片、視訊、HTML 文件、軟體應用程式、信用卡事務、電子郵件等。

(9)瀏覽器通過HTTP請求伺服器HTML 資源步驟:

        1、 瀏覽器從URL 中解析出伺服器的主機名;

        2、瀏覽器將伺服器的主機名轉換成伺服器的IP 地址;

        3、瀏覽器將埠號(如果有的話)從URL 中解析出來;

        4、瀏覽器建立一條與Web 伺服器的TCP 連線;

        5、 瀏覽器向伺服器傳送一條HTTP 請求報文;

        6、 伺服器向瀏覽器回送一條HTTP 響應報文;

        7、關閉連線,瀏覽器顯示文件。

 

二、http封裝的基礎

(1)HttpHeaders:表示HTTP報文首部,首部內容為客戶端和伺服器分別處理請求和響應提供所需要的資訊。HTTP首部欄位是由首部欄位名和欄位值構成的,中間用冒號分隔(首部欄位名: 欄位值)。該類同時也為首部欄位提供了get/set方法。HTTP 首部欄位根據實際用途被分為以下 4 種類型:

        1、通用首部欄位(General Header Fields):請求報文和響應報文兩方都會使用的首部。

        2、請求首部欄位(Request Header Fields):從客戶端向伺服器端傳送請求報文時使用的首部。補充了請求的附加內容、客戶端資訊、響應內容相關優先順序等資訊。

        3、響應首部欄位(Response Header Fields):從伺服器端向客戶端返回響應報文時使用的首部。補充了響應的附加內容,也會要求客戶端附加額外的內容資訊。

        4、實體首部欄位(Entity Header Fields):針對請求報文和響應報文的實體部分使用的首部。補充了資源內容更新時間等與實體有關的資訊。

(2)ReadOnlyHttpHeaders:只讀型別的HTTP報文首部。繼承自HttpHeaders,只能讀取,不能寫入。

 

(3)HttpEntity:表示HTTP request或者response實體,由header首部和body主體兩部分組成。

(4)RequestEntity:繼承自HttpEntity,Request請求實體,在HttpEntity基礎上增加了兩個屬性:HttpMethod類和URI類。HttpMethod枚舉了HTTP請求報文的幾種方法:GET/HEAD/POST/PUT/PATCH/DELETE/OPTIONS/TRACE。URI(java.net.URI)表示統一資源識別符號(URI)引用。HttpEntity主要被RestTemplate使用(package org.springframework.web.client,RestTemplate 對 http 的封裝類似 JdbcTemplate 對 jdbc 的封裝,能夠以 rest 風格的方式,以 GET/POST/PUT/DELETE/HEAD/ OPTIONS 等不同的方式向伺服器發起HTTP 請求)。

(5)ResponseEntity:繼承自HttpEntity,Response響應實體,在HttpEntity基礎上增加了一個屬性HttpStatus。HttpStatus枚舉了HTTP的狀態碼。1xx訊息、2xx成功、3xx重定向、4xx客戶端錯誤、5xx伺服器錯誤,每條HTTP響應報文返回時都會攜帶一個狀態碼,告知客戶端請求是否成功,或者是否需要採取其他動作。同樣,該類主要被RestTemplate使用。

 

(6)HttpMessage:HTTP request請求報文和response響應報文的父介面。提供了一個方法getHeaders(),獲得該報文的首部HttpHeaders。

(7)HttpRequest(extends HttpMessage):表示一個HTTP request請求報文。在父類基礎上新增了兩個函式:getMethod()獲取報文的HttpMethod,描述了伺服器應該執行的操作方法;getURI()獲取該報文的URL,描述了要對哪個資源執行上述方法。

(8)HttpInputMessage(extends HttpMessage):表示一條接收到的HTTP報文,從伺服器端來看就是接收到request報文,從客戶端來看就是接收到response報文。在父介面HttpMessage定義的函式getHeaders()基礎上新增了一個函式getBody(),獲得報文的主體,返回型別是可讀的位元組輸入流InputStream(java.io.InputStream)。

(9)HttpOutputMessage(extends HttpMessage):表示一條傳送出去的HTTP報文,從伺服器端來看就是傳送出去的response報文,從客戶端來看就是傳送出去的request報文。在父介面HttpMessage定義的函式getHeaders()基礎上新增了一個函式getBody(),獲得報文的主體,返回型別是可寫的位元組輸入流OutputStream(java.io.OutputStream)。

(10)StreamingHttpOutputMessage(extends HttpOutputMessage):繼承自HttpOutputMessage,該報文允許設定一個streaming流型別的報文主體。相應的,這種報文型別也就不支援getBody()函式讀取報文主體了。

(11)ReactiveHttpInputMessage(extends HttpMessage):一個響應式的HTTP input報文,會將這個input報文當做Publisher釋出者暴露。這個介面主要會被伺服器端接收到的request請求報文類或者客戶端接收到的response響應報文類實現。reactive programming(響應式程式設計)是相對於imperative programming(指令式程式設計)而言的,一種非同步程式設計風格,它關注資料流和變化的傳播。

(12)ReactiveHttpOutputMessage(extends HttpMessage):一個響應式的HTTP output報文,會將這個output報文當做Publisher傳送出去。這個介面主要會被伺服器端傳送的response響應報文類或者客戶端傳送的request請求報文類實現。

(13)ZeroCopyHttpOutputMessage(extends ReactiveHttpOutputMessage):在類ReactiveHttpOutputMessage繼承上增加了對零拷貝的檔案傳輸的支援。零拷貝技術(Zero-Copy)是指將資料直接從磁碟檔案複製到網絡卡裝置中,而不需要經由應用程式之手 。零拷貝大大提高了應用程式的效能,減少了核心和使用者模式之間的上下文切換 。

 

(14)MediaType:繼承自MimeType(org.springframework.util.MimeType),在父類MimeType基礎上增加了對在HTTP規範中定義的一些高質量的引數提供的方法支援。媒體型別決定瀏覽器將以何種形式對資源進行解析。常見的媒體格式型別(<type>/<subtype>)如下:

        text/html: HTML格式

        text/plain:純文字格式

        image/gif:gif圖片格式

        application/pdf:pdf格式

        application/octet-stream:二進位制流資料

        ...

 Content-Type實體頭部用於指示資源的MIME型別media type。如:

        Content-Type: text/html; charset=utf-8

        Content-Type: multipart/form-data; boundary=something

(15)MediaTypeEditor:繼承自PropertyEditorSupport(java.beans.PropertyEditorSupport),自動的把字串型別的說明(如"text/html")轉換成MediaType物件。

(16)MediaTypeFactory:該工廠類用來從資源控制代碼或者檔名中解析出MediaType物件。

(17)InvalidMediaTypeException:執行解析函式parseMediaType(String)時遇到一個非法的media type丟擲的異常。

 

(18)HttpMethod:枚舉了HTTP request 幾種方法:GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS、TRACE。該列舉型別主要被ClientHttpRequest(package  org.springframework.http)和RestTemplate(package org.springframework.web.client)使用。

        列舉是Java1.5引入的新特性,通過關鍵字enum來定義列舉類。列舉類是一種特殊類,它和普通類一樣可以使用構造器、定義成員變數和方法,也能實現一個或多個介面,但列舉類不能繼承其他類。

(19)HttpStatus:枚舉了HTTP的狀態碼。通過提供的series()函式可以得到該狀態碼屬於哪一大類:INFORMATIONAL(1xx訊息)、SUCCESSFUL(2xx成功)、REDIRECTION(3xx重定向)、CLIENT_ERROR(4xx客戶端錯誤)、SERVER_ERROR(5xx伺服器錯誤)。

(20)HttpRange:使用Range首部來表示一個HTTP(byte) range。HTTP通過首部Range屬性允許客戶端只請求文件的一部分,或者說某個範圍。

        GET /bigfile.html HTTP/1.1

        Host: www.joes-hardware.com

        Range: bytes=4000-

        User-Agent: Mozilla/4.61 [en] (WinNT; I)

        ...

        在上例中,客戶端請求的是文件開頭4000 位元組之後的部分(不必給出結尾位元組數,因為請求方可能不知道文件的大小)。在客戶端收到了開頭的4000 位元組之後就失敗的情況下,可以使用這種形式的範圍請求。

        還可以用Range 首部來請求多個範圍(這些範圍可以按任意順序給出,也可以相互重疊)。例如,假設客戶端同時連線到多個伺服器,為了加速下載文件而從不同的伺服器下載同一個文件的不同部分。對於客戶端在一個請求內請求多個不同範圍的情況,返回的響應也是單個實體,它有一個多部分主體及Content-Type: multipart/byteranges 首部。Range 首部在流行的點對點(Peer-to-Peer,P2P)檔案共享客戶端軟體中得到廣泛應用,它們從不同的對等實體同時下載多媒體檔案的不同部分。

(21)CacheControl:控制快取的開關,用於標識請求或響應中是否開啟了快取,使用了哪種快取方式。

1、在請求中使用Cache-Control時,可選的值有:

        no-cache:告知(代理)伺服器不直接使用快取,要求向原伺服器發起請求。

        no-store:所有內容都不會被儲存到快取或Internet臨時檔案中。

        max-age=delta-seconds:告知伺服器客戶端希望接收一個存在時間不大於delta-seconds秒的資源。

        max-stale[=delat-seconds] :告知(代理)伺服器客戶端願意接收一個超過快取時間的資源,若有定義delta-seconds則為delta-seconds秒,若沒有則為任意超出時間。

        min-fresh=delta-seconds:告知(代理)伺服器客戶端希望接收一個在小於delta-seconds秒內被更新過的資源。

        no-transform:告知(代理)伺服器客戶端希望獲取試題資料沒有被轉換(比如壓縮)過的資源。

        only-if-cached:告知(代理)伺服器客戶端希望獲取快取的內容(若有),而不用向伺服器發去請求。

        cache-extension:自定義拓展值,若伺服器不識別該值將被忽略掉。

2、在響應中使用Cache-Control時,可選的值有:

        public:表明任何情況下都得快取該資源(即使是需要HTTP認證的資源)。

        Private[=”field-name”] :表明返回報文中全部或部分(若指定了field-name則為field-name的欄位資料)僅開放給某些使用者(伺服器指定的share-user,如代理伺服器)做快取使用,其他使用者則不能快取這些資料。

        no-cache:不直接使用快取,要求向伺服器發起請求。

        no-store:所有內容都不會被儲存到快取或Internet臨時檔案中。

        no-transform:告知客戶端快取檔案時不得對實體資料做任何改變。

        only-if-cached:告知(代理)伺服器客戶端希望獲取快取的內容(若有),而不用向原伺服器發去請求。

        must-revalidate:當前資源一定是向原伺服器發去驗證請求的,若請求失敗會返回504(而非代理伺服器上的快取)

        proxy-revalidate:與must-revalidate類似,但僅能應用於共享快取(如代理)。

        max-age=delta-seconds:告知客戶端該資源在delta-seconds秒內是新鮮的,無需向伺服器發請求。

        s-maxage=delta-seconds:同max-age,但僅應用於共享快取(如代理)

        cache-extension:自定義拓展值,若伺服器不識別該值將被忽略掉。

(22)ContentDisposition:該類表示在RFC 6266中定義的屬性Content-Disposition。Content-Disposition 屬性是作為對下載檔案的一個標識欄位,有兩種型別:inline 和 attachment。inline :將檔案內容直接顯示在頁面;attachment:彈出對話方塊讓使用者下載。RFC 6266正式將Content-Disposition納入 HTTP 標準。

(23)HttpLogging:如果"org.springframework.web"日誌功能開啟,但是"org.springframework.http"日誌功能沒有開始,那麼此時建立一個共享的日誌記錄器(命名為org.springframework.web.HttpLogging),用來記錄和HTTP相關的日誌。這也就是說"org.springframework.web"會開啟所有web日誌記錄器,包括一些低層級的包(如"org.springframework.http")和模組(比如來自於spring-core被包裝進EncoderHttpMessageWriter或DecoderHttpMessageReader的編解碼器)。

(24)HttpCookie:用來表示一條HTTP cookie,以name-value(名稱-鍵值對)形式表示。

        HTTP協議是無狀態的協議,一旦資料交換完畢,客戶端與伺服器端的連線就會關閉,再次交換資料需要建立新的連線。這就意味著伺服器無法從連線上跟蹤會話。Cookie就是這樣的一種機制。它可以彌補HTTP協議無狀態的不足,是http協議的一個擴充套件。

        有兩個http頭部是專門負責設定以及傳送cookie的,它們分別是Set-Cookie(響應報文首部)以及Cookie(請求報文首部)。當伺服器返回給客戶端一個http響應資訊時,其中如果包含Set-Cookie這個頭部時,意思就是指示客戶端建立一個cookie,並且在後續的http請求中自動傳送這個cookie到伺服器端,直到這個cookie過期。如果cookie的生存時間是整個會話期間的話,那麼瀏覽器會將cookie儲存在記憶體中,瀏覽器關閉時就會自動清除這個cookie。另外一種情況就是儲存在客戶端的硬碟中,瀏覽器關閉的話,該cookie也不會被清除,下次開啟瀏覽器訪問對應網站時,這個cookie就會自動再次傳送到伺服器端。

(25)ResponseCookie:繼承自HttpCookie,增加了Set-Cookie 響應首部的一些屬性。下面是Set-cookie一個簡單的例子:

        HTTP/1.0 200 OK

        Set-cookie: id="34294"; domain="joes-hardware.com"

        Content-type: text/html

        Content-length: 1903

        最初的cookie 規範是由網景公司定義的。這些“ 版本0” 的cookie 定義了Set-Cookie 響應首部、cookie 請求首部以及用於控制cookie 的欄位。版本0(網景)的Set-Cookie屬性:

        1、NAME=VALUE:強制的,伺服器可以建立任意的NAME=VALUE關聯,在後續對站點的訪問中會將其送回給伺服器。

        2、Expires:可選的,該屬性用來指定一個日期字串,用來定義cookie的實際生存期。一旦到了過了生存日期,就不再儲存或者釋出這個cookie了。

        3、Domain:可選的。瀏覽器只向指定域中的伺服器傳送cookie。

        4、Path:可選的。這個屬性可以為伺服器上特定的文件分配cookie。

        5、Secure:可選的。如果包含了這一屬性,就只有在HTTP使用SSL安全連線時才會傳送cookie。

 

三、client端的request請求(傳送出去的)/response響應(接收到的)

        client端的類主要有三種:

        ClientHttpRequest表示一個客戶端傳送的HTTP request請求報文(包括基本實現類及支援Buffering、Streaming、Async、StreamingAsync、BufferingAsync拓展類)。

        ClientHttpResponse表示一個客戶端接收到的HTTP response響應報文。(包括基本實現類和支援Async拓展類)。

        ClientHttpRequestFactory用來建立ClientHttpRequest的工廠(包括基本實現類和支援Async拓展類)。

        上述又分為基於jkd自帶功能、Apache的HttpClient、OkHttp3、Netty4的實現。使用Apache的HttpClient、OkHttp3、Netty4都可,但這些都需要額外導包,預設情況下Spring使用的是java.net.HttpURLConnection。

(一)http/client/

介面

(1)ClientHttpRequest:表示一個客戶端的request請求報文。繼承自HttpRequest、 HttpOutputMessage(因為從客戶端看request是傳送出去的,所以繼承自HttpOutputMessage。同理,客戶端的ClientHttpResponse是接收到的報文,繼承自HttpInputMessage)。通過ClientHttpRequestFactory工廠的實現類建立。該介面定義了一個函式execute(),函式的返回型別就是ClientHttpResponse。

(2)ClientHttpResponse:表示客戶端接收到的HTTP response響應報文。繼承自HttpInputMessage、Closeable。通過執行ClientHttpRequest的execute()函式獲得。

(3)ClientHttpRequestFactory:建立ClientHttpRequest物件的工廠。定義了一個函式createRequest(URI, HttpMethod),根據URI和HttpMethod創建出一個ClientHttpRequest來發送請求。

(4)ClientHttpRequestInitializer:回撥介面,在ClientHttpRequest使用之前先對其初始化。

(5)ClientHttpRequestExecution:表示客戶端HTTP request報文執行(execute)的上下文。主要在ClientHttpRequestInterceptor使用,用來在一個攔截器鏈上呼叫下一個攔截器,如果到了攔截器末尾,執行request本身。

(6)ClientHttpRequestInterceptor:客戶端的Http request請求攔截器,在Http訊息傳送到伺服器前,該方法被呼叫,對Http Request報文做些處理,比如加頭,更改請求的URL,授權等等。對於客戶端接收到的ClientHttpResponse也能處理。

 

(7)AsyncClientHttpRequest:繼承自HttpRequest、HttpOutputMessage,表示客戶端一個非同步的HTTP request請求,通過工廠類建立。(Spring4.0新增,Spring 5.0中廢棄,使用org.springframework.web.reactive.function.client.ClientRequest替代)

應用層的網路模型有同步與非同步。同步意味當前執行緒是阻塞的,只有本次請求完成後才能進行下一次請求;非同步意味著所有的請求可以同時塞入緩衝區,不阻塞當前的執行緒。

(8)AsyncClientHttpRequestFactory:建立AsyncClientHttpRequest的工廠,。通過函式createAsyncRequest(URI, HttpMethod)建立。(Spring4.0新增,Spring 5.0中廢棄,使用org.springframework.http.client.reactive.ClientHttpConnector替代)

(9)AsyncClientHttpRequestExecution:ClientHttpRequestExecution非同步拓展。(Spring4.3新增,Spring 5.0中廢棄,使用org.springframework.web.reactive.function.client.ExchangeFilterFunction替代)

(10)AsyncClientHttpRequestInterceptor:ClientHttpRequestInterceptor非同步拓展。(Spring4.3新增,Spring 5.0中廢棄,使用org.springframework.web.reactive.function.client.ExchangeFilterFunction替代)

 

抽象類

(11)AbstractClientHttpRequest:實現介面ClientHttpRequest,確保首部和報文體不會多次寫入。

(12)AbstractBufferingClientHttpRequest:繼承自AbstractClientHttpRequest。在request請求報文傳送出去之前,快取request body,內部private ByteArrayOutputStream bufferedOutput變數儲存了request body的內容,避免流的二次讀取會導致讀取不到資料。

(13)AbstractAsyncClientHttpRequest:實現 AsyncClientHttpRequest介面的抽象類。( Spring 5.0中廢棄,使用org.springframework.http.client.reactive. AbstractClientHttpRequest替代。)

(14)AbstractBufferingAsyncClientHttpRequest:同時拓展了非同步和快取功能的request報文,繼承自AbstractAsyncClientHttpRequest。(Spring 5.0中廢棄,無直接替代者)。

 

(15)AbstractClientHttpResponse:實現介面ClientHttpResponse。

(16)AbstractClientHttpRequestFactoryWrapper:裝飾抽象類,實現介面ClientHttpRequestFactory,裝飾另一個request factory。裝飾模式建立了一個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。裝飾類一般是一個抽象類,屬性裡有一個private變數指向ClientHttpRequestFactory,通過建構函式傳遞給被該修飾者,createRequest方法委託給被修飾者執行。

 

裝飾器類

(17)BufferingClientHttpRequestWrapper:包裝另外一個request。

(28)BufferingClientHttpResponseWrapper:實現ClientHttpResponse介面。考慮到多次呼叫getBody(),將接收到的response報文的body部分讀入到記憶體中。

(19)BufferingClientHttpRequestFactory:ClientHttpRequestFactory的裝飾器,使得具有快取的能力。若開啟快取功能(有開關可控),會使用BufferingClientHttpRequestWrapper包裝原來的ClientHttpRequest。這樣傳送請求後得到的是BufferingClientHttpResponseWrapper響應。

 

(20)InterceptingClientHttpRequest:包裝了ClientHttpRequest,支援HTTP 請求攔截器 ClientHttpRequestInterceptor。該類重寫了executeInternal方法,通過內部類InterceptingRequestExecution實現interceptors順序執行。該內部類中的的execute()方法的特點是:若存在攔截器,交給給攔截器去執行傳送請求return nextInterceptor.intercept(request, body, this),否則就自己上。

(21)InterceptingAsyncClientHttpRequest:包裝了AsyncClientHttpRequest,該類重寫了executeInternal方法,通過內部類AsyncRequestExecution實現AsyncClientHttpRequestInterceptor順序執行。該內部類中的的executeAsync()方法的特點是:若存在攔截器,交給給攔截器去執行傳送請求:

        return interceptor.intercept(request, body, this);

否則就自己上:

        delegate = requestFactory.createAsyncRequest(uri, method);

        return delegate.executeAsync();

(22)InterceptingClientHttpRequestFactory:繼承自AbstractClientHttpRequestFactoryWrapper。包裝ClientHttpRequestFactory,以支援ClientHttpRequestInterceptor(客戶端的Http request請求攔截器,在Http訊息傳送到伺服器前,該方法被呼叫,對Http Request報文做些處理)。

(23)InterceptingAsyncClientHttpRequestFactory:實現介面AsyncClientHttpRequestFactory。包裝AsyncClientHttpRequestFactory,以支援AsyncClientHttpRequestInterceptor。(Spring 5.0,廢棄,無代替者)

 

        在介紹下面類之前,先總體介紹下ClientHttpRequest和ClientHttpRequestFactory在不同庫下的實現:

        ClientHttpRequest它代表請求的客戶端,該介面繼承自HttpRequest、HttpOutputMessage,只有一個ClientHttpResponse execute() throws IOException方法。其中HttpUrlConnection 、OkHttp3、Netty、HttpComponents對它都有實現。預設情況下Spring使用的是java.net.HttpURLConnection,也可以使用OkHttp3、Netty4、Apache的HttpClient,但這些都需要額外導包。

        ClientHttpRequestFactory是一個函式式介面,用於根據URI和HttpMethod創建出一個ClientHttpRequest來發送請求。根據使用底層http庫的不同可以分為:

        1、SimpleClientHttpRequestFactory:Spring內建ClientHttpRequestFactory預設的實現,它使用JDK工具(來自java.net包的類),因此不依賴於第三方庫。

        2、OkHttp3ClientHttpRequestFactory:封裝OkHttp 3.x

        3、Netty4ClientHttpRequestFactory:封裝Netty 4。(Spring 5.0中廢棄,使用org.springframework.http.client.reactive.ReactorClientHttpConnector替代)。

        4、HttpComponentsClientHttpRequestFactory:封裝Apache的HttpClient。

 

使用JDK內建庫

(24)SimpleBufferingClientHttpRequest:ClientHttpRequest介面的實現類,帶緩衝功能。通過SimpleClientHttpRequestFactory建立。

(25)SimpleStreamingClientHttpRequest:ClientHttpRequest介面的實現類,能執行流處理請求,通過SimpleClientHttpRequestFactory建立。

(26)SimpleBufferingAsyncClientHttpRequest:繼承自AbstractBufferingAsyncClientHttpRequest,通過SimpleClientHttpRequestFactory建立。

(27)SimpleStreamingAsyncClientHttpRequest:繼承自AbstractAsyncClientHttpRequest,能執行流處理請求,通過SimpleClientHttpRequestFactory建立。

(28)SimpleClientHttpResponse:ClientHttpResponse介面實現類,通過執行SimpleBufferingClientHttpRequest的函式execute()或者SimpleStreamingClientHttpRequest的函式execute()獲得。

(29)SimpleClientHttpRequestFactory:ClientHttpRequestFactory介面的實現類,繼承自ClientHttpRequestFactory和AsyncClientHttpRequestFactory。重寫了ClientHttpRequestFactory的createRequest()函式(用來生成上面24、25兩種型別的request)和AsyncClientHttpRequestFactory的createAsyncRequest()函式(用來生成上面26、27兩種型別的request)。

 

使用OkHttp 3.x框架

        OkHttp是一款優秀的HTTP框架,一個處理網路請求的開源專案,是安卓端的輕量級框架,由移動支付Square公司貢獻。支援get請求和post請求,支援基於Http的檔案上傳和下載,支援載入圖片,支援下載檔案透明的GZIP壓縮,支援響應快取避免重複的網路請求,支援使用連線池來降低響應延遲問題。導包示例:

        <dependency>

            <groupId>com.squareup.okhttp3</groupId>

            <artifactId>okhttp</artifactId>

            <version>3.14.0</version>

        </dependency>

(30)OkHttp3ClientHttpRequest:基於OkHttp 3.x的ClientHttpRequest介面的實現類。通過OkHttp3ClientHttpRequestFactory建立。

(31)OkHttp3AsyncClientHttpRequest:基於OkHttp 3.x的AsyncClientHttpRequest介面的實現類。通過OkHttp3ClientHttpRequestFactory建立。(Spring 5.0中廢棄,無替代者)。

(32)OkHttp3ClientHttpResponse:基於OkHttp 3.x的ClientHttpResponse介面實現類。通過執行OkHttp3ClientHttpRequest的executeInternal()函式獲得。

(33)OkHttp3ClientHttpRequestFactory:ClientHttpRequestFactory介面的實現類,基於OkHttp 3.x建立request,createRequest()函式建立OkHttp3ClientHttpRequest;createAsyncRequest()函式建立OkHttp3AsyncClientHttpRequest。

 

使用Netty 4框架

        Netty是由JBOSS提供給的一個java開源框架。Netty提供非同步的、事件驅動的網路應用框架和工具,用以快速開發高效能、高可靠的網路伺服器和客戶端程式。導包示例:

        <dependency>

            <groupId>io.netty</groupId>

            <artifactId>netty-all</artifactId>

            <version>5.0.0.Alpha2</version>

        </dependency>

(34)Netty4ClientHttpRequest:基於Netty 4的ClientHttpRequest介面的實現類,通過Netty4ClientHttpRequestFactory建立。

(35)Netty4ClientHttpResponse:基於Netty 4的ClientHttpResponse介面的實現類。

(36)Netty4ClientHttpRequestFactory :ClientHttpRequestFactory介面的實現類,基於Netty 4建立Netty4ClientHttpRequest。

 

使用Apache的HttpClient框架

        Apache開源組織的HttpComponents 也就是以前的httpclient專案,可以用來提供高效的、最新的、功能豐富的支援 HTTP 協議的客戶端/伺服器程式設計工具包,支援 HTTP 協議最新的版本和建議。現在的 HttpComponents 包含多個子專案:HttpComponents Core、HttpComponents Client、HttpComponents AsyncClient、Commons HttpClient。導包示例:

        <dependency>

            <groupId>org.apache.httpcomponents</groupId>

            <artifactId>httpclient</artifactId>

            <version>4.5.10</version>

        </dependency>

(37)HttpComponentsClientHttpRequest:基於Apache HttpComponents HttpClient的ClientHttpRequest介面的實現類。通過(42)HttpComponentsClientHttpRequestFactory建立。

(38)HttpComponentsStreamingClientHttpRequest:基於Apache HttpComponents HttpClient的執行流處理請求的ClientHttpRequest介面的實現類。通過(42)HttpComponentsClientHttpRequestFactory建立。

(39)HttpComponentsAsyncClientHttpRequest:基於Apache HttpComponents HttpAsyncClient的ClientHttpRequest介面的實現類,通過(43)HttpComponentsAsyncClientHttpRequestFactory建立。(Spring 5.0中廢棄,無替代者)

(40)HttpComponentsClientHttpResponse:基於Apache HttpComponents HttpClient的ClientHttpResponse介面的實現類。通過(37)HttpComponentsClientHttpRequest的executeInternal()函式建立。

(41)HttpComponentsAsyncClientHttpResponse:基於Apache HttpComponents HttpAsyncClient的ClientHttpResponse介面的實現類。通過(39)HttpComponentsAsyncClientHttpRequest建立。(Spring 5.0中廢棄,無替代者)

(42)HttpComponentsClientHttpRequestFactory:ClientHttpRequestFactory介面的實現類,基於Apache HttpComponents HttpClient建立request。通過createRequest()函式來建立(37)HttpComponentsClientHttpRequest(bufferRequestBody屬性為true情況下,屬性bufferRequestBody用來表示該工廠是否需要在內部快取request body,預設為true)或者(38)HttpComponentsStreamingClientHttpRequest(bufferRequestBody屬性為false情況下,如果通過POST或者PUT方法傳送大量的資料,推薦設定為false,以防止快取溢位)。

(43)HttpComponentsAsyncClientHttpRequestFactory:繼承自HttpComponentsClientHttpRequestFactory,基於Apache HttpComponents HttpAsyncClient 4.0建立(39)HttpComponentsAsyncClientHttpRequest(Spring 5.0中廢棄,無替代者)

 

(44)MultipartBodyBuilder:為multipart請求類準備請求體,以MultiValueMap<String, HttpEntity>形式返回。http協議採納了多部物件集合(multipart),multipart 請求類主要是對檔案上傳進行的處理,傳送一份報文主體內可含有多個型別實體,通常在圖片或者文字上傳時使用,其中郵件上傳各種附件的機制也是用了MIME的Mulipart方法。

(二)http/client/reactive

        reactive programming(響應式程式設計)是一種非同步程式設計風格,它關注資料流和變化的傳播,與之相對應的是imperative programming(指令式程式設計)。

        在指令式程式設計中,a:=b+c意味著將b+c的結果賦值給a,並且此後b或c的值發生變化不會影響到a的值。而在響應式程式設計中,a的值會隨著b或c的改變而自動更新,並且不需要重新執行a:=b+c來確定當前分配給a的值。例如,在 model–view–controller (MVC) 架構中,響應式程式設計可以促進基礎模型中的更改,這些更改會自動反映在關聯的檢視中。

        如果從推拉的角度來看的話,響應式程式設計是“推”,它主動將變化推送給它的訂閱者。Publisher-Subscriber是兩個非常重要的概念。本質來講,響應式程式設計上是對資料流或某種變化所作出的反應,但是這個變化什麼時候發生是未知的,所以他是一種基於非同步、回撥的方式在處理問題

 

介面

(1)ClientHttpRequest:繼承自ReactiveHttpOutputMessage的介面,表示一個客戶端的響應式HTTP request請求報文。

(2)ClientHttpResponse:繼承自ReactiveHttpInputMessage的介面,表示一個客戶端的響應式HTTP response響應報文。

(3)ClientHttpConnector:客戶端的HTTP聯結器介面,從HTTP客戶端抽象出來的一個功能,使HTTP客戶端連線到伺服器上,也提供了傳送ClientHttpRequest和接收ClientHttpResponse所有必要的基礎設施。

抽象類

(4)AbstractClientHttpRequest:上述ClientHttpRequest介面實現的抽象類。

裝飾器類

(5)ClientHttpRequestDecorator:ClientHttpRequest的裝飾器。

(6)ClientHttpResponseDecorator:ClientHttpResponse的裝飾器。

 

Jetty ReactiveStreams HTTP client

Jetty 是一個開源的servlet容器,適用於一個通用的Reactive Streams API。

(7)JettyClientHttpRequest:繼承自AbstractClientHttpRequest。

(8)JettyClientHttpResponse:ClientHttpResponse介面實現類。

(9)JettyClientHttpConnector:ClientHttpConnector介面實現類。

(10)JettyResourceFactory:在Spring的ApplicationContext容器生命週期範圍內,用來管理Jetty資源的工廠,比如Executor、ByteBufferPool、Scheduler。該工廠實現了InitializingBean、DisposableBean介面。一般被宣告為Spring管理bean。

 

Reactor-Netty HTTP client

        Netty是一個java開源框架,適用於一個通用的Reactive Streams API。

(11)ReactorClientHttpRequest:繼承自AbstractClientHttpRequest、ZeroCopyHttpOutputMessage。

(12)ReactorClientHttpResponse:ClientHttpResponse介面實現類。

(13)ReactorClientHttpConnector:ClientHttpConnector介面實現類。

(14)ReactorResourceFactory:在Spring的ApplicationContext容器生命週期範圍內,用來管理Reactor Netty資源的工廠,比如LoopResources、ConnectionProvider。該工廠實現了InitializingBean、DisposableBean介面。一般被宣告為Spring管理bean。

(三)http/client/support

(1)HttpAccessor:作為RestTemplate的基類或者其他HTTP訪問閘道器的助手類。定義了一些通用的屬性,如ClientHttpRequestFactory。

(2)AsyncHttpAccessor:作為AsyncRestTemplate的基類或者其他HTTP訪問閘道器的助手類。定義了一些通用的屬性,如AsyncClientHttpRequestFactory。

(3)InterceptingHttpAccessor:繼承自HttpAccessor,增加了一些攔截器相關的屬性。

(4)InterceptingAsyncHttpAccessor:繼承自AsyncHttpAccessor,增加了請求攔截功能。

 

(5)BasicAuthenticationInterceptor:ClientHttpRequestInterceptor介面的實現類,使用username/password做一個HTTP基本認證,除非的Authorization header設定好了。

(6)BasicAuthorizationInterceptor:ClientHttpRequestInterceptor介面的實現類,使用一個基本的 Authorization 訊息頭。

 

(7)HttpRequestWrapper:HttpRequest裝飾器類。

(8)ProxyFactoryBean:實現ProxyFactoryBean、InitializingBean介面,用於生成代理物件java.net.Proxy。重寫了InitializingBean的afterPropertiesSet函式,這個方法在所有的屬性被初始化後但是在init前呼叫。

 

四、server端的request請求(接收到的)/response響應(傳送出去的)

(一)http/server/

(1)PathContainer:介面,將通過執行函式parsePath(String)得到的URI path結構化表示成一系列的分隔符和PathSegment。

(2)DefaultPathContainer:PathContainer介面的預設實現。

(3)RequestPath:繼承自PathContainer的介面,表示一個請求報文完整的路徑。

(4)DefaultRequestPath:RequestPath介面的預設實現。

 

(5)ServerHttpRequest:繼承自HttpRequest、HttpInputMessage的介面,表示伺服器端接收到的HTTP request請求報文。

(6)ServerHttpResponse:繼承自HttpOutputMessage、Flushable、Closeable的介面,表示伺服器端傳送出去的HTTP response響應報文。

(7)ServerHttpAsyncRequestControl:一個控制元件介面,能將對HTTP request請求報文的處理置於非同步模式下,在response響應處於open的狀態下直至明確關閉。

 

(8)ServletServerHttpRequest:基於HttpServletRequest的ServerHttpRequest介面的實現類。

        HttpServletRequest(javax.servlet.http.HttpServletRequest)繼承自ServletRequest,代表客戶端的請求,當客戶端通過HTTP協議訪問伺服器時,HTTP請求頭中的所有資訊都封裝在這個物件中,包含了客戶端請求資訊包括請求的地址,請求的引數,提交的資料,上傳的檔案客戶端的ip甚至客戶端作業系統都包含在其內。通過這個物件提供的方法,可以獲得客戶端請求的所有資訊。

(9)ServletServerHttpResponse:基於HttpServletResponse的ServerHttpResponse介面的實現類。

        HttpServletResponse繼承了ServletResponse介面,代表伺服器的響應。這個物件中封裝了向客戶端傳送資料、傳送響應頭,傳送響應狀態碼的方法。並提供了與Http協議有關的方法,這些方法的主要功能是設定HTTP狀態碼和管理Cookie。

(10)ServletServerHttpAsyncRequestControl:實現了介面AsyncListener、ServerHttpAsyncRequestControl,在Servlet容器(Servlet 3.0+)上使用。

(二)http/server/reactive

(1)AbstractListenerReadPublisher:實現介面Publisher的抽象類,用來在event-listener read APIs 和Reactive Streams建立聯絡。具體來說就是使用Servlet 3.1 non-blocking I/O和Undertow XNIO讀取HTTP request請求體,此外也可以使用標準的Java WebSocket (JSR-356)、Jetty、Undertow處理剛收到的WebSocket訊息。

(2)AbstractListenerServerHttpResponse:抽象類,作為基於listener的伺服器端響應報文 的父類,比如Servlet 3.1和Undertow。

 

(3)AbstractListenerWriteProcessor:實現Processor介面的抽象類,用來在event-listener write APIs 和Reactive Streams建立聯絡。具體來說就是使用Servlet 3.1 non-blocking I/O和Undertow XNIO寫入HTTP request請求體,此外也可以使用標準的Java WebSocket (JSR-356)、Jetty、Undertow寫入WebSocket訊息。

(4)AbstractListenerWriteFlushProcessor:實現Processor介面的抽象類,AbstractListenerWriteProcessor的一個替代類,不同的是在每一個巢狀Publisher都完成後,writing a Publisher with flush boundaries enforces。

 

(5)ChannelSendOperator:考慮一個用source Publisher寫的寫函式,返回的結果是一個result Pulisher,這個操作符的作用就是推遲這個寫函式的呼叫,直到我們確定source Publisher將會無錯誤的釋出。

(6)DefaultServerHttpRequestBuilder:ServerHttpRequest.Builder介面的預設實現類。

(7)WriteResultPublisher:實現Publisher介面,該釋出者通過執行ServerHttpResponse的writeWith(Publisher)函式得到。

        Publisher是一個可以提供 0-N 個序列元素的提供者,並根據其訂閱者Subscriber的需求推送元素。一個Publisher可以支援多個訂閱者,並可以根據訂閱者的邏輯進行推送序列元素。Reactor中有兩種Publisher:Flux和Mono,其中Flux用來表示0-N個元素的非同步序列,Mono用來表示0-1個元素的非同步序列。

        1、Flux 是一個發出(emit)0-N個元素組成的非同步序列的Publisher<T>,可以被onComplete訊號或者onError訊號所終止。在響應流規範中存在三種給下游消費者呼叫的方法 onNext、onComplete和onError。

        2、Mono 是一個發出(emit)0-1個元素的Publisher<T>,可以被onComplete訊號或者onError訊號所終止。

(8)SslInfo:SSL 會話資訊的控制代碼。SSL(Secure Sockets Layer 安全套接字協議)是為網路通訊提供安全及資料完整性的一種安全協議。

(9)DefaultSslInfo:SslInfo介面的預設實現。

 

(10)JettyHeadersAdapter:實現MultiValueMap介面,用於包裝Jetty HTTP headers。

        MultiValueMap即一個鍵對應多個值,我們平時使用的Map一個key只能對應一個value,如果想要一個key對應多個value,通常我們會將多個value放到一個集合中。sping對此做了簡單的封裝,封裝之後的介面為MultiValueMap。

Netty、Undertow、Tomcat、Jetty都是web容器,都適用於一個通用的Reactive Streams API。

(11)NettyHeadersAdapter:實現MultiValueMap介面,用於包裝Netty HTTP headers。

(12)TomcatHeadersAdapter:實現MultiValueMap介面,用於包裝Tomcat HTTP headers。

(13)UndertowHeadersAdapter:實現MultiValueMap介面,用於包裝Jetty HTTP headers。

 

(14)HttpHandler:一個對於HTTP請求的略偏底層的協定, 規範了Tomcat、Jetty、Netty、Undertow、Servlet3.1等伺服器。 旨在對於不同的Web伺服器提供更加抽象統一的介面。更高一級的通用模組,如WebFilter、WebSession、ServerWebExchange在org.springframework.web.server包中。應用級別程式設計模型,如註解控制器和功能處理程式在spring-webflux模組中。

(15)ContextPathCompositeHandler:HttpHandler介面實現類。

(16)ReactorHttpHandlerAdapter:介面卡,適配HttpHandler和處理Netty channel響應式函式。實現了介面BiFunction<HttpServerRequest, HttpServerResponse, Mono<Void>>,HttpServerRequest表示函式的第一個引數的型別,HttpServerResponse表示函式的第二個引數的型別,Mono<Void>表示函式結果的型別。方法apply​(reactorRequest, reactorResponse)將此函式應用於給定的引數。

 

(17)ServletHttpHandlerAdapter:介面卡,適配HttpHandler和HttpServlet

(18)TomcatHttpHandlerAdapter:繼承自ServletHttpHandlerAdapter,對ServletHttpHandlerAdapter介面卡做了拓展,使用Tomcat APIs讀取接收到的request請求報文或者寫入要傳送出去的response響應報文。

(19)JettyHttpHandlerAdapter:繼承自ServletHttpHandlerAdapter,對ServletHttpHandlerAdapter介面卡做了拓展,使用Jetty APIs寫入要傳送出去的response響應報文。

(20)UndertowHttpHandlerAdapter:實現介面io.undertow.server.HttpHandler,適配HttpHandler和io.undertow.server.HttpHandler。

 

(21)ServerHttpRequest:繼承自HttpRequest,ReactiveHttpInputMessage的介面。表示一個響應式的伺服器端接收到的HTTP request請求報文。

(22)ServerHttpResponse:繼承自ReactiveHttpOutputMessage的介面。表示一個響應式的伺服器端傳送出去的HTTP response響應報文。

 

(23)AbstractServerHttpRequest:ServerHttpRequest介面實現的抽象類。

(24)AbstractServerHttpResponse:ServerHttpResponse介面實現的抽象類。

 

(25)ServerHttpRequestDecorator:ServerHttpRequest裝飾類。

(26)ServerHttpResponseDecorator:ServerHttpResponse裝飾類。

(27)HttpHeadResponseDecorator:繼承自ServerHttpResponseDecorator,HTTP request使用head方法的請求報文(HEAD方法請求一個與GET請求的響應相同的響應,但沒有響應體)返回的響應報文ServerHttpResponse的裝飾類。

 

(28)ServletServerHttpRequest:Servlet伺服器端收到的請求報文。

(29)ServletServerHttpResponse:Servlet伺服器端傳送出去的響應報文。

 

(30)ReactorServerHttpRequest:Reactor伺服器端收到的請求報文。

(31)ReactorServerHttpResponse:Reactor伺服器端傳送出去的響應報文。

 

(32)UndertowServerHttpRequest:Undertow伺服器端收到的請求報文。

(33)UndertowServerHttpResponse:Undertow伺服器端傳送出去的響應報文。

 

五、格式的轉換,如json,rss,xml等

(一)http/converter/

(1)HttpMessageConverter:策略介面, HTTP request 請求報文和response響應報文的轉換器,將請求資訊轉換為一個物件(型別為T),將物件(型別為T)輸出為響應資訊。該介面有5個方法:獲取該轉換器支援的 MediaType列表(getSupportedMediaTypes),判斷接收到request是否能讀(canRead),判斷能否寫傳送出去的報文(canWrite),讀取接收到的報文(read),寫入要傳送的報文(write)。

(2)AbstractHttpMessageConverter:大部分HttpMessageConverter介面實現類的抽象基類。通過setSupportedMediaTypes(List)函式可以設定支援的MediaTypes,在寫入要傳送出去的訊息時增加了對Content-Type和Content-Length支援。

(3)GenericHttpMessageConverter:繼承自HttpMessageConverter的介面,用來將一個HTTP request報文轉換成指定通用型別的目標物件,或者將一個指定通用型別的源物件轉換成一個HTTP response報文。

(4)AbstractGenericHttpMessageConverter:大部分GenericHttpMessageConverter介面實現類的抽象基類。

 

(5)ByteArrayHttpMessageConverter:將request資訊轉換為byte陣列,或者將byte陣列輸出為response資訊。

(6)StringHttpMessageConverter:將request資訊轉換為String型別,或者將String型別輸出為response資訊。

(7)ObjectToStringHttpMessageConverter:使用StringHttpMessageConverter對content進行讀寫,使用ConversionService對String content和目標物件進行相互轉換。

(8)FormHttpMessageConverter:將request資訊轉換為HTML表單,或者將HTML表單輸出為response資訊,或者將MultiValueMap<String, String>輸出為response資訊(但是不會將request資訊轉換成MultiValueMap)。

(9)BufferedImageHttpMessageConverter:將request資訊轉換為BufferedImage,或者將BufferedImage輸出為response資訊。

(10)ResourceHttpMessageConverter:將request資訊轉換為Resources,或者將Resources輸出為response資訊。預設情況下,該轉換器可以讀取所有型別的media(讀取request),能輸出到response中的型別在MediaTypeFactory定義。

(11)ResourceRegionHttpMessageConverter:將一個或者一批ResourceRegion輸出為response資訊。

(二)http/converter/cbor

MappingJackson2CborHttpMessageConverter:能使用專用的Jackson 2.x拓展庫對CBOR格式的資料進行讀寫。簡明二進位制物件展現(CBOR,Concise Binary Object Representation)是一種提供良好壓縮性,擴充套件性強,不需要進行版本協商的二進位制資料交換形式。

(三)http/converter/feed

(1)AbstractWireFeedHttpMessageConverter:作為AtomFeedHttpMessageConverter和RssChannelHttpMessageConverter的基類,使用了Rome開源包。

Feed:訊息來源,是一種資料格式,網站通過它將最新資訊傳播給使用者。將feed匯流於一處稱為聚合。RSS是站點用來和其他站點之間共享內容的一種簡易方式(也叫聚合內容),通常被用於新聞和其他按順序排列的網站,例如Blog。ATOM是Rss的一個替代品。RSS和ATOM兩種訂閱方式出形式都是FEED。Rome是為RSS聚合而開發的開源包。

(2)AtomFeedHttpMessageConverter:轉換Atom feeds。

(3)RssChannelHttpMessageConverter:轉換RSS feeds。

(四)http/converter/json

        json (JavaScript Object Notation) 是javascript物件的一種形態,一種輕量級的資料交換格式,易於人閱讀和編寫,同時也易於機器解析和生成,廣泛應用於各種資料的互動中,尤其是伺服器與客戶端的互動。

        json有兩種資料型別:json和jsonb,而兩者唯一的區別在於效率,json是對輸入的完整拷貝,使用時再去解析,所以它會保留輸入的空格,重複鍵以及順序等。而jsonb是解析輸入後儲存的二進位制,它在解析時會刪除不必要的空格和重複的鍵,順序和輸入可能也不相同。使用時不用再次解析。兩者對重複鍵的處理都是保留最後一個鍵值對。效率的差別:json型別儲存快,使用慢,jsonb型別儲存稍慢,使用較快。

        Java操作json的庫有:JSON-B 、Jackson、Gson和fastjson。

        Java EE8 中新的 JSON Binding API (JSON-B) 支援在 Java 物件與JSON之間序列化和反序列化。從功能上講,JSON-B API包含兩個入口點介面:javax.json.bind.Jsonb和javax.json.bindJsonBuilder。Jsonb介面分別通過方法toJson()和fromJson()實現序列化和反序列化。JsonBuilder介面基於一組可選的操作而構造Jsonb例項,併為客戶端提供對例項的訪問權。

        Jackson 是一個 Java 的用來處理 JSON 格式資料的類庫。

        Fastjson 是一個 Java 庫,可以將 Java 物件轉換為 JSON 格式,當然它也可以將 JSON 字串轉換為 Java 物件。

        Gson(又稱Google Gson)是Google公司釋出的一個開放原始碼的Java庫,主要用途為序列化Java物件為JSON字串,或反序列化JSON字串成Java物件。使用如下例所示:

public class User{
   //省略帶參構造方法
  private int id;
  private String userName;
}
User user = new User(1,"zs");
String userJson = gson.toJson(user);  // 序列化user物件為 {"id":1,"userName":"zs"}
user = gson.fromJson(userJson,User.class);  //反序列化

(1)AbstractJsonHttpMessageConverter:JSON轉換器的基類,比如GSON和JSON-B。

 

(2)JsonbHttpMessageConverter:使用JSON-B庫的JSON轉換器。

 

(3)MappingJacksonValue:MappingJackson2HttpMessageConverter要執行序列化操作(將Java物件序列化為JSON字串)的簡單Java物件。

(4)MappingJacksonInputMessage:此message用來儲存一個Jsonb例項,該message會被進行反序列化成Java物件。

(5)Jackson2ObjectMapperBuilder:構建器,使用流式 API介面來建立ObjectMapper例項。ObjectMapper類是Jackson庫的主要類。ObjectMapper類的readValue API 可以解析或反序列化json內容為java物件。 反之,writeValue API可以序列化任何java物件為json字串。

(6)Jackson2ObjectMapperFactoryBean:一個FactoryBean,用來建立Jackson 2.x ObjectMapper物件(預設情況下),或者XmlMapper物件(createXmlMapper屬性設定為true情況下)。

(7)SpringHandlerInstantiator:通過Spring 的ApplicationContext容器建立Jackson自動裝配的JsonSerializer、JsonDeserializer、KeyDeserializer、TypeResolverBuilder、TypeIdResolver的beans。

(8)AbstractJackson2HttpMessageConverter:基於Jackson、與Content-Type無關的HttpMessageConverter介面實現類的抽象基類。

(9)MappingJackson2HttpMessageConverter:HttpMessageConverter介面的實現類,使用Jackson 2.x的ObjectMapper對JSON進行轉換。

 

(10)GsonFactoryBean:FactoryBean,用來建立一個Google Gson 2.x Gson例項。

(11)GsonBuilderUtils:取得Google Gson 2.x  GsonBuilder功能類。GsonBuilder用來生成Gson物件,規定Gson的序列化和返序列化時的格式等內容。

(12)GsonHttpMessageConverter:HttpMessageConverter介面實現類,使用Google Gson庫來對JSON進行轉換。

(五)http/converter/protobuf

(1)ExtensionRegistryInitializer:Google協議訊息能夠包含可以被解析的訊息拓展,如果相應的配置資訊在ExtensionRegistry中已經被註冊過。該介面使用協議訊息拓展來初始化ExtensionRegistry

(2)ProtobufHttpMessageConverter:使用Google Protocol Buffers來對com.google.protobuf.Messages進行轉換。

(3)ProtobufJsonFormatHttpMessageConverter:ProtobufHttpMessageConverter的子類,使用Protobuf 3和它的官方庫在對JSON處理上做了增強。Protobuf是google開發的一種跨語言和平臺的序列化資料結構的方式,類似於XML但是更小更快而且更簡單,只需要定義一次結構體,通過生成的原始碼可以在不同的資料流和不同的語言平臺上去讀寫資料結構。最新的protobuf3支援更多的語言使用,比如go、object-c等。

(六)http/converter/smile

MappingJackson2SmileHttpMessageConverter:使用Jackson 2.x專用的拓展對Smile資料格式(binary JSON)進行轉換。

        BSON(binary json)是10gen開發的一個數據格式,目前主要用於MongoDB中,是MongoDB的資料儲存格式。BSON基於JSON格式,普通JSON標記和BSON之間的主要區別在於BSON是JSON的二進位制標記版本。由於BSON更緊湊,因此在反序列化時它具有更少的開銷,並且對於大型和複雜的有效載荷來說是更好的選擇。

(七)http/converter/support

AllEncompassingFormHttpMessageConverter:FormHttpMessageConverter轉換器的拓展,增加了對XML和JSON-based parts的支援。

(八)http/converter/xml

(1)AbstractXmlHttpMessageConverter:用來轉換XML的轉換器的抽象基類。繼承該抽象類的轉換器支援text/xml、application/xml、application/*-xml。

(2)AbstractJaxb2HttpMessageConverter:使用JAXB2的轉換器的抽象基類。getJaxbContext()函式用來為指定的類建立JAXBContext。

  &nbs