於是我看了下httpservletresponse的getoutputstream方法,看看它注釋是怎麼說的。
/**以上,注釋有說明是outputstream是用來寫響應body內容的,也有提到flush()方法,說明肯定是有緩衝的,所以應該不是直接操作socket寫資料。我猜測應該是有乙個位元組陣列用來暫時儲存,然後統一flush。但是還是不太確定,於是簡單翻閱了下tomcat原始碼。* returns a suitable for writing binary
* data in the response. the servlet container does not encode the
* binary data.
** calling flush() on the servletoutputstream commits the response.
** either this method or may
* be called to write the body, not both, except when
* has been called.**
@return
a for writing binary data **
@exception
illegalstateexception if the
getwriter
method* has been called on this response**
@exception
ioexception if an input or output exception occurred**
@see
#getwriter
* @see
#reset
*/public servletoutputstream getoutputstream() throws ioexception;
找到servletoutputstream的實現類coyoteouputstream。它實現了outputstream的抽象方法write,把資料寫入到outputbuffer型別的字段中存著。而這個outputbuffer物件來自於coyote/response。其實這個outputbuffer也只是乙個介面,具體實現一直向下翻是streamoutputbuffer。資料大小沒有限制,是用鍊錶儲存的,每個鍊錶節點儲存8196位元組。
其實就是檢視,它是何時呼叫outputbuffer的flush方法的。我逐層檢視,最終定位到了connector/response的finishresponse()方法。這個方法,會先傳送響應行和響應頭。然後再傳送響應body。tomcat的原始碼我看的不多,這裡找到一張不錯的時序圖,描述的是乙個http請求的處理過程。如下,我們把重點放在servlet的service方法呼叫,和response的fininshresponse方法呼叫上。可以得到,在service方法返回後,執行的就是finishresponse操作。也就是說,當servlet程式處理完這個請求後,tomcat就會把響應結果發回客戶端
注意:servlet的程式不參與底層資料的收發,或者說不控制
servlet的service方法呼叫在圖中**?
servlet程式處理請求指的是什麼?
根本上servlet程式做的工作就是,根據request的資訊,填充response資訊而已。
servlet程式與spring mvc是什麼關係?
那mvc的返回頁面,返回rest資料是怎麼回事?
《how tomcat works》中講到,servlet容器(tomcat就是一種servlet容器)的任務有概括地講有三個
1.建立乙個request物件,並填充相關資訊(parameters、headers、cookie、uri等)
2.建立乙個response物件
3.呼叫與此請求關聯的servlet的service方法,把request和response傳給它。
這裡我用自己的話講一下:當瀏覽器向服務端發來乙個請求時,服務端會將請求資料報的內容解析出來,建立乙個填充有請求資訊的request物件,同時建立乙個"空的"response物件,然後把這兩個物件傳給servlet的service方法,讓它來完成response物件的填充,最後把response資料傳送給客戶端。
為什麼要傳request物件?
你不傳request物件,servlet程式就不知道該填充什麼。換句話說,它不知道你到底想要什麼資源。
tomcat是如何找到請求關聯的servlet的?
我們知道,tomcat在開發的時候不可能知道你會往它裡面部署什麼專案,servlet程式叫什麼。所以它不可能硬編碼來呼叫service方法,它所使用的就是反射機制。
當請求來臨時,先根據projectname找到對應專案,再根據後續的url對映到對應的servlet類名。之後tomcat就會利用反射機制載入servlet類檔案,獲取例項,然後再呼叫service方法。
coyote/response主要就是跟底層的資料傳遞掛鉤的,而connector/response是coyote/response的上層包裝,它實現了httpservletresponse介面。但是如果將它直接傳給service方法,則害怕使用者直接將httpservletresponse強轉為connector/response,直接呼叫底層的一些方法。所以引入了乙個使用"facade模式",將connector/response除了httpservletresponse介面定義的public方法都遮蔽掉。也就是說,傳遞給service的實際上是connector/responsefacade物件,就算強轉為實際型別,也只能看到httpservletresponse介面定義的方法。
神經網路的輸入何時是任意大小,何時是固定的
影象進行卷積的時候,因為每乙個卷積核中權值都是共享的,因此無論輸入影象的尺寸是多大的都可以都是按照步長滑動做卷積,只不過都是經過卷積運算,不同大小的輸入提取出的卷積特徵的大小也是不同的。但是,全連線層的乙個神經元對應乙個輸入。換句話說,全連線層要求固定的輸入維度。而不同大小的影象,卷積模組 卷積 非...
platform的probe函式是何時被呼叫的
這幾天搞ti的vpfe,裡面裝置的註冊使用platform,平台裝置註冊方式來註冊的。一直都知道 裡的probe函式,但是不知道是何時被呼叫的。經過跟蹤 在module init vpfe init 模組初始化的時候,vpfe init函式中呼叫了 這裡 err driver register vp...
雜談,我為什麼要開始寫部落格。
目的3 可以成為更好的自己 寫在最後 其實一開始也是深夜想著想著自己不能夠這麼頹廢下去,偶然看到朋友之前寫的部落格已經陸續的更新,我心裡面也就想著,我也該行動了。於是我就走在了路上。在我們學習生活中,遇到的問題,以及遇到問題的解決辦法。往往會解完就放在一邊,時間一久往往會記不清放在了 然而生活中的問...