1. 程式人生 > >HttpServletRequest對象

HttpServletRequest對象

request httpservletrequest requestfacade


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中較為常用的一些方法:

獲得服務器相關信息方法:

方法名稱

作用

getInputStream()

獲得本次通信的Input流對象

getServerName()

獲得服務器的名稱

getServerPort()

獲得服務器的端口

getContextPath()

獲得web工程的路徑

getLocale()

獲得區域所使用的語言


代碼示例:

技術分享


運行結果:

技術分享




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

方法名稱

作用

getHeader(String)

參數為鍵,獲得該鍵的值

getHeaderNames()

返回所有的鍵

getHeaders(String)

參數為鍵,獲得拆分的值

getContentLength()

獲得網頁文件的長度,沒有的話就會返回-1

getContentType()

獲得網頁文件的類型

getMethod()

獲得請求的方法

getQueryString()

獲得請求的參數,但是要註意:只有get類型的請求方式才有效果

getRequestURI()

獲得訪問的目標Servlet所在工程下的那一部分內容

getRequestURL()

獲得整個URL


代碼示例:

技術分享


運行結果:

技術分享




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

方法名稱

作用

getRemoteAddr()

獲得客戶端IP地址

getRemoteHost()

獲得客戶端IP地址

getRemotePort()

獲得客戶端端口


代碼示例:

技術分享


運行結果:

技術分享





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

方法名稱

作用

setCharacterEncoding(String)

設置表單提交上來的文本編碼

getParameter(String)

得到表單中某一個指定的name屬性的值

getParameterMap()

獲得所有的鍵值對

getParameterNames()

獲得所有的name屬性的值:

getParameterValues(String)

獲得重復的name屬性的值


Html代碼示例:

技術分享


Java代碼示例:

技術分享

技術分享


瀏覽器表單:

技術分享


控制臺結果:

技術分享





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

方法名稱

作用

getAttribute(String)

獲得屬性對象

getAttributeNames()

獲得所有的屬性名稱

removeAttribute(String)

刪除參數中字符串描述的屬性

setAttribute(String, Object)

設置屬性和屬性的值,這是鍵/值對形式的

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


代碼示例:

技術分享


瀏覽器:

技術分享


控制臺結果:

技術分享

























本文出自 “zero” 博客,請務必保留此出處http://zero01.blog.51cto.com/12831981/1979476

HttpServletRequest對象