官术网_书友最值得收藏!

3.4 請求

請求對象封裝了客戶端請求的所有信息。在HTTP協議中,這些信息包含在從客戶端發送到服務器請求的HTTP頭部和消息體中。

3.4.1 HTTP協議參數

Servlet的請求參數以字符串的形式作為請求的一部分從客戶端發送到Servlet容器。當請求是一個HttpServletRequest對象且符合“參數可用時”描述的條件時,容器從URI查詢字符串和POST數據中填充參數。參數以一系列的名-值對(name-value)的形式保存。任何給定的參數的名稱可存在多個參數值。ServletRequest接口的以下方法可訪問這些參數:

  • getParameter
  • getParameterNames
  • getParameterValues
  • getParameterMap

getParameterValues方法返回一個String對象的數組,包含了與參數名稱相關的所有參數值。

getParameter方法的返回值必須是getParameterValues方法返回的String對象數組中的第一個值。

getParameterMap方法返回請求參數的一個java.util.Map對象,其中以參數名稱作為Map鍵,參數值作為Map值。

查詢字符串和POST請求的數據被匯總到請求參數集合中。查詢字符串數據放在POST數據之前。例如,請求由查詢字符串a=hello和POST數據a=goodbye&a=world組成,得到的參數集合順序將是a=(hello, goodbye, world)。

這些API不會暴露GET請求(HTTP 1.1所定義的)的路徑參數。它們必須從getRequestURI方法或getPathInfo方法返回的字符串值中解析。

post表單數據填充到參數集(Parameter Set)前必須滿足以下條件:

  • 該請求是一個HTTP或HTTPS請求。
  • HTTP方法是POST。
  • 內容類型是application/x-www-form-urlencoded。
  • 該Servlet已經對請求對象的任意getParameter方法進行了初始調用。

如果不滿足這些條件,而且參數集中不包括post表單數據,那么Servlet必須可以通過請求對象的輸入流得到post數據。如果滿足這些條件,那么從請求對象的輸入流中直接讀取post數據將不再有效。

3.4.2 屬性

屬性是與請求相關聯的對象。屬性可以由容器設置來表達信息,否則無法通過API表示,或者由Servlet設置將信息傳達給另一個Servlet(通過RequestDispatcher)。屬性通過ServletRequest接口中的以下方法來訪問:

  • getAttribute
  • getAttributeNames
  • setAttribute

一個屬性名稱只能關聯一個屬性值。

3.4.3 請求頭

通過下面的HttpServletRequest接口方法,Servlet可以訪問HTTP請求的頭信息:

  • getHeader
  • getHeaders
  • getHeaderNames

getHeader方法返回給定頭名稱的頭。多個頭可以具有相同的名稱,例如HTTP請求中的Cache-Control頭。如果多個頭的名稱相同,getHeader方法就返回請求中的第一個頭。getHeaders方法允許訪問所有與特定頭名稱相關的頭值,返回一個String對象的Enumeration(枚舉)。

頭可包含String形式的Int或Date數據。HttpServletRequest接口提供如下方法訪問這些類型的頭數據:

  • getIntHeader
  • getDateHeader

如果getIntHeader方法不能轉換為Int的頭值,就拋出NumberFormatException異常。如果getDateHeader方法不能把頭轉換成一個Date對象,就拋出IllegalArgumentException異常。

3.4.4 請求路徑元素

引導Servlet服務請求的請求路徑由許多重要部分組成:

    URI = Context Path + Servlet Path + PathInfo

其中:

  • Context Path:與ServletContext相關聯的路徑前綴是這個Servlet的一部分。如果這個上下文是基于Web服務器的URL命名空間的“默認”上下文,那么這個路徑將是一個空字符串。否則,如果上下文不是基于服務器的命名空間,那么這個路徑以“/”字符開始,但不以“/”字符結束。
  • Servlet Path:路徑部分直接與激活請求的映射對應。這個路徑以“/”字符開頭,如果請求與“/*”或“”模式匹配,在這種情況下,它是一個空字符串。
  • PathInfo:請求路徑的一部分,不屬于Context Path或Servlet Path。如果沒有額外的路徑,它要么是null,要么是以“/”開頭的字符串。使用HttpServletRequest接口中的以下方法來訪問這些信息:

 getContextPath

 getServletPath

 getPathInfo

表3-1展示了請求路徑元素的使用例子。

表3-1 請求路徑元素的使用例子

3.4.5 路徑轉換方法

在Servlet API中有兩個方便的方法,允許開發者獲得與某個特定的路徑等價的文件系統路徑。這兩個方法是:

  • ServletContext.getRealPath
  • HttpServletRequest.getPathTranslated

getRealPath方法需要一個String參數,并返回一個String形式的路徑,這個路徑對應一個在本地文件系統上的文件。getPathTranslated方法推斷出請求的pathInfo的實際路徑。

這些方法在Servlet容器無法確定一個有效的文件路徑的情況下返回null,比如Web應用程序不能訪問遠程文件系統上的本地文件。JAR文件中META-INF/resources目錄下的資源只有當調用getRealPath()方法時才認為容器已經從包含它的JAR文件中解壓,在這種情況下必須返回解壓縮后的位置。

3.4.6 請求數據編碼

目前,很多HTTP請求并不一定會在Content-Type頭上設置字符編碼限定符。如果客戶端請求沒有指定請求默認的字符編碼,那么容器用來創建請求讀取器和解析POST數據的編碼必須是ISO-8859-1。

如果客戶端沒有設置字符編碼,并使用不同的編碼來編碼請求數據,而不是使用上面描述的默認的字符編碼,那么可能會發生問題。為了彌補這種情況,開發人員可以通過下面幾種方法來覆蓋由容器提供的字符編碼:

  • *ServletContext上提供了setRequestCharacterEncoding(String enc)。
  • web.xml中提供了元素。
  • ServletRequest接口上提供了setCharacterEncoding(String enc)。

必須在解析任何post數據或從請求讀取任何輸入之前調用上述方法。上述方法一旦調用,將不會影響已經讀取的數據的編碼。

主站蜘蛛池模板: 潞西市| 上高县| 西贡区| 涡阳县| 三河市| 沂南县| 静安区| 乌鲁木齐市| 浠水县| 绥滨县| 江油市| 沈丘县| 尤溪县| 临潭县| 宣恩县| 秦安县| 胶州市| 错那县| 吉首市| 大宁县| 樟树市| 景德镇市| 谢通门县| 孝感市| 白城市| 广元市| 织金县| 庆阳市| 阜新| 临夏县| 呈贡县| 巴南区| 浦县| 黎平县| 湛江市| 旌德县| 梁平县| 资兴市| 枝江市| 达拉特旗| 页游|