1. 程式人生 > >JavaEE——HttpServletRequest對象

JavaEE——HttpServletRequest對象

兩個類 acad 客戶 -s 一個 解釋權 tps alt 打印

聲明:本欄目所使用的素材都是凱哥學堂VIP學員所寫,學員有權匿名,對文章有最終解釋權;凱哥學堂旨在促進VIP學員互相學習的基礎上公開筆記。

HttpServletRequest對象

我們都知道瀏覽器通過http協議與Tomcat(web服務器)通信時,會生成兩個對象,一個是HttpServletRequest對象,一個是HttpServletResponse對象。它們是一對數據封裝對象,前者封裝客戶端的請求頭,後者封裝服務器的響應頭。而在這裏要介紹的是HttpServletRequest對象,HttpServletRequest實際上是個接口,是Java所定制的接口,這個接口是由開發web服務器的人員去做實現的。
可以看一下HttpServletRequest的源碼:

技術分享

我們可以看看Tomcat中實現這個接口的兩個類:
Request類:

技術分享

RequestFacade類:

技術分享

可以看到以上這兩個類都各自實現了HttpServletRequest接口,但實際上這個兩個類是有關聯的,具體的代碼實現其實是由Request類完成的,而RequestFacade類只是作為一個轉發的存在。而且從類的名稱上也可以看得出來,Facade是外觀、正面的意思,所以這是一個外觀類,而在這個RequestFacade類後面的真正實現類是Request。可以想象成RequestFacade是Request的前端、門面,Request則是RequestFacade的後臺、後端。
看一下RequestFacade的構造器和部分代碼就知道了:

技術分享

再來看看RequestFacade的部分代碼:

技術分享

而且這個類的代碼行數也不到一千行:

技術分享

下面再來看看Request類的代碼:

技術分享

可以看到getContextPath這個方法是在Request類上實現的,並且因為實現代碼在這個類裏,所以代碼行數比RequestFacade類多:

技術分享

示意圖:

技術分享

從上圖可以看到HttpServletRequest接口和Request、RequestFacade實現類之間構成了一個模式,這個設計模式就是外觀模式。外觀模式為子系統中的一組接口提供了一個一致的界面,這個界面就是RequestFacade,並且定義了一個高層接口這個接口就是HttpServletRequest,這個接口使得這一子系統更加容易使用。
外觀模式好處在於隱藏了系統的復雜性,並向客戶端提供了一個客戶端可以訪問系統的接口(HttpServletRequest)。這種類型的設計模式屬於結構型模式,它向現有的系統添加一個接口,來隱藏系統的復雜性,這個模式實現了子系統與客戶端之間的松耦合關系。所以我們都是通過HttpServletRequest接口對象去調用方法的,而實現類和界面類都隱藏在背後,而且這兩個類也不是Java實現的,而是開發web服務器的人員實現的(Java的尿性一貫如此)。

關於對象池:
HttpServletRequest和HttpServletResponse對象是存放在一個對象池中的,這是一個活動的能夠自動增長的對象池,就和自動增長的線程池一樣,每當對象不夠用的時候就會新增加對象。這個對象池可以優化服務器資源,因為這兩個對象可以反復的利用,不會造成資源的浪費。如果沒有這個對象池的話,每次用戶訪問就會新建一次對象的話,這麽做十分耗費資源,而且速度還慢。所以從這一點可以知道,這個對象池就是起到了一個優化資源的作用(好像池子都是這麽回事)。
我們可以打印這個兩個對象的hash值查看一下就知道了(需要不斷的刷新訪問頁面):

技術分享

運行結果:

技術分享

從圖中可以看到有幾個hash值重復了好幾次,所以從這一點就可以得知它使用了對象池機制。

好了,以上簡單介紹完HttpServletRequest中接口與實現類的一些關系和使用到了什麽設計模式與對象池機制,接下來介紹一下HttpServletRequest中較為常用的一些方法:
獲得服務器相關信息方法:

技術分享

代碼示例:

技術分享

運行結果:

技術分享

獲得請求頭信息方法(請求頭中的信息是鍵/值對形式的):

技術分享

代碼示例:

技術分享

運行結果:

技術分享

獲得客戶端的IP和端口方法:

技術分享

代碼示例:

技術分享

運行結果:

技術分享

獲得和設置表單數據方法(如果是上傳文件的話則無法獲取文件中的數據):

技術分享

Html代碼示例:

技術分享

Java代碼示例:

技術分享

技術分享

瀏覽器表單:

技術分享

控制臺結果:

技術分享

獲得和設置表單屬性相關方法:

技術分享

註意:以上這幾個方法只是在web容器內部流轉,僅在具有轉發關系的Web組件之間共享,也就說只在這個範圍內有效,所以不能直接把值獲得到代碼中打印,以下使用實際示例演示一下就知道無法直接獲得值了:

代碼示例:

技術分享

瀏覽器:

技術分享

控制臺結果:

技術分享

JavaEE——HttpServletRequest對象