request、response 的複習總結
文章目錄
概述
servlet最主要的作用就是處理客戶端的請求,並及時向客戶端做出響應。爲此,對於servlet的每次請求,服務器在調用 service()
方法之前,都會創建兩個對象 — 即 HttpServletRequest 對象和 HttpServletResponse 對象。
其中,HttpServletRequest 用於封裝 http 請求消息,稱爲 request 對象;HttpServletResponse 用於封裝 http 響應消息,稱爲 response 對象。
注:服務器運行階段,每個servlet都只會創建一個實例對象。但對於每次的http請求都會調用該servlet實例的 service(HttpServletRequest request, HttpServletResponse response
方法重新創建一個 request 對象和 response 對象。
1.request 對象
1.1 HttpServletRequest 簡介
在servlet中,HttpServletRequest 接口繼承自 ServletRequest 接口,專門用於封裝 http 請求消息。對應於 http 請求消息的請求行、請求消息頭和請求消息體,HttpServletRequest 接口中定義了獲取請求行、請求消息頭和請求消息體的方法。
1.2 獲取請求行相關方法
在 http 請求行中,包含請求方法、請求資源名、請求路徑等等信息,對應這些消息, HttpServletRequest 接口定義了一系列用於獲取請求行的方法:
方法 | 功能描述 | 注意 |
---|---|---|
String getMethod() |
獲取http請求消息的請求方式(如get,post等) | GET/POST |
String getRequestURI() |
獲取請求行中的資源名稱 | 地址欄主機和端口之後,參數之前的內容 |
String getQueryString() |
獲取請求行中的參數內容 | 請求地址(?)以後的所有內容 |
String getContextPath() |
獲取請求URL中屬於WEB應用程序的路徑(返回上下文路徑),這個路徑以’/'開頭,表示相對於整個WEB站點的根目錄 | 應用較多** |
String getServletPath() |
獲取當前Servlet的名稱或Servlet映射的路徑 | |
String getRemoteAddr() |
獲取請求客戶端的IP地址 | IPV4或IPV6地址 |
String getRemoteHost() |
獲取請求客戶端的完整主機名(如果無法解析出客戶端的完整主機名,將返回客戶端的IP地址) | |
int getRemotePort() |
獲取請求客戶端網絡連接的端口號 | |
String getServletName() |
獲取當前請求所指向的主機名 | |
String getServletPort() |
獲取當前請求所連接的服務器端口號 | |
String getScheme() |
獲取請求的協議名 | http,https,ftp等 |
StringBuffer getRequestURL() |
獲取客戶端發出請求時完整URL,包括協議,服務器名、端口號、資源路徑等信息,但不包括參數 | 注意區分URL和URI |
說着簡單,動手實踐一下比什麼都清楚:
方法使用:
直接在地址欄輸入:http://localhost:8888/MyServletTest01/Test00Servlet?name=zhangsan 帶參數訪問Test00Servlet
1.3 獲取請求消息頭相關方法
http 請求消息中,需要通過請求頭向服務器傳遞附加信息,如:客戶端可以接收的數據類型(以便設置相應消息的數據),請求消息體的字符集編碼等,HttpServletRequest 接口也定義有一系列用於獲取 http 請求頭字段的方法:
1)String getHeader(String name)
此方法用於獲取一個指定頭字段的值(類似於key-value),如果請求中沒有相應的頭字段,返回 null;如果請求消息中包含有多個指定名稱的頭字段,返回其中第一個頭字段的值。
2)Enumeration getHeaders(String name)
此方法返回一個 Enumeration 集合對象,該集合對象由請求消息中出現的某個指定名稱的所有頭字段的值組成(大多數情況下,一個頭字段在請求消息中只出現一次,但有時可能會出現多次)。此方法去除 參數 name 即可用於獲取請求頭消息中所有頭字段的值(同樣返回 Enumeration 集合對象)
3)int getIntHeader(String name)
用於獲取指定名稱的頭字段,並且將其值轉化爲 int 類型;若指定名稱的頭字段不存在,返回值爲-1;若獲取到的頭字段的值不能轉化爲 int 類型,則報錯(異常)
4)String getContentType()
獲取 Content-Type 頭字段的值,結果爲 String 類型;如果請求是GET,那麼這個方法返回null
5)int getContentLength()
獲取 Content-Length 頭字段的值,結果爲 int 類型;GET請求沒有請求體,返回-1
6)String getCharacterEncoding()
此方法返回請求消息的實體部分的字符集編碼,通常是從 Content-Type 頭字段中進行提取,結果爲 String 類型;對於GET而言,沒有請求體!所以此方法只能對POST請求中的參數有效
1.3 獲取請求參數相關方法(重點:拿小本本記着)
在實際開發中,經常需要獲取用戶提交的表單數據,或者鏈接中的參數,爲了方便獲取這些參數,HttpServletRequest 接口的父類 ServletRequest 中定義了一系列獲取請求參數的方法:
1)String getParameter(String name)
獲取某個指定名稱的參數值;若請求消息中沒有包含指定名稱的參數,返回null;若指定名稱的參數存在但沒有設置值,返回空字符串(與null不同);若請求消息中包含多個該指定名稱的參數,則返回第一個出現的參數值
2)String[] getParameterValues(String name)
http 請求消息中可以有多個相同名稱的參數(如表單的多選框等),如果要獲取請求消息中同一個名稱所對應的所有參數值,即可使用
String[] getParameterValues(String name)
。此方法返回一個 String 類型的數組
3)Enumeration getParameterNames()
返回一個包含請求消息中所有參數名的 Enumeration 對象。通過此方法,可以對請求消息中的所有參數進行遍歷處理
4)Map getParameterMap()
此方法將請求消息中的所有參數名和對應的值裝入一個 Map 對象中,並返回此 Map 對象
5)InputStream getInputStream()
返回的一個代表實體內容的輸入流對象,其類型爲
javax.servlet.ServletInputStream
6)BufferedReader getReader()
返回的一個代表實體內容的 BufferedReader 對象,返回的 BufferedReader 對象將實體內容中的字節數據按照請求消息中指定的字符集編碼轉換成文本字符串
注:getParameter、getInputStream、getReader 都是從selvlet中request對象得到提交的數據,但是用途不同;要根據 form 表單提交數據的編碼方式( form表單的一個關鍵屬性:enctype)選擇不同的方法。
1.enctype=application/x- www-form-urlencoded
是表單默認的編碼方式,編碼後的結果通常是field1=value1&field2=value2&… 的形式,如 name=aaaa&password=bbbb…
通常的表單都是採用這種方式進行編碼,此時只需要簡單地通過 getParameter 方法即可獲取用戶表單提交的數據
2.multipart/form-data
此編碼方式用於傳輸大塊的二進制數據,客戶端將表單內的數據和文件放在一起發送。
以這種方式編碼的表單,則需要使用 getInputStream 或 getReader 方法(getParameter 無法獲取這種編碼方式下提交的數據)
3.這3種方法是有衝突的(表單中提交的數據以流形式被讀取,流只能被讀一次);在第一種編碼方式下,3種方法都有衝突,只能使用其中一種方法(建議使用 getParameter);在第二種編碼方式下,因爲 getParameter 無法讀取數據,故只有 getInputStream 和 getReader 方法之間存在衝突,只能使用一種方法讀取
2.response 對象
2.1 HttpServletResponse 簡介
在servlet中,HttpServletResponse 接口繼承自 ServletResponse 接口,專門用於封裝 http 響應消息。對應於 http 響應消息的狀態行、響應消息頭和消息體,HttpServletResponse 接口中定義了向客戶端發送響應狀態碼、響應消息和響應消息體的方法。
2.2 發送狀態碼相關方法
當 servlet 向客戶端返回響應消息時,需要在響應消息中設置狀態碼。對此,HttpServletResponse 中定義了發送狀態碼的方法:
1)setStatus(int sc)
方法
該方法用於設置 http 響應消息的狀態碼,並生成響應狀態行(包括http協議的版本和狀態描述信息),狀態行的狀態描述信息直接與狀態碼相關,而http協議的版本由服務器直接確定,所以,只需要通過 setStatus(int sc) 方法設置了狀態碼即可實現狀態行的生成)。
正常情況下,服務器會默認產生一個狀態碼爲200的狀態行,即 — HTTP/1.1 200 OK
2)sendError(int sc)
方法
該方法用於發送表示錯誤信息的狀態碼,如,404表示找不到客戶端請求的資源。在 response 對象中,提供了兩個重載的 sendError 方法:
1.public void sendError(int sc)
2.public void sendError(int sc, String msg)
第一個方法只發送錯誤信息的狀態碼;第二個方法除了發送狀態碼外,還增加了一條用於提示說明的 String 字符串信息(將出現在發送給客戶端的正文內容中)
2.3 發送響應消息頭相關方法
當 servlet 向客戶端發送響應消息時,對應 http 協議的多種響應字段,HttpServletResponse 接口定義有一系列設置 http 響應頭字段的方法:
1)addHeader(String name,String value)
setHeader(String name,String value)
上述兩個方法用於設置 HTTP 協議的響應頭字段,其中 name 指定響應頭字段名稱,value 指定對應的值(好比 key-value 形式),addHeader 方法可以增加同名的響應頭字段(key是可以重複的),而 setHeader 方法則會覆蓋同名的頭字段(修改原來的)
2)addIntHeader(String name,int value)
setIntHeader(String name,int value)
這兩個方法專用於設置包含整數值的響應頭(避免前二個方法使用時需要將int類型轉換爲String類型)
3)setContentLength(int len)
該方法用於設置響應消息的實體內容的大小,單位是字節。對於 http 協議,這個方法就是設置Content-Length 響應頭字段的值
4)setContentType(String type)
此方法用於設置Servlet輸出內容的MIME類型;對於 http 協議,就是設置 Content-Type 響應頭字段的值。例如:如果發送到客戶端的內容是 .jpg 格式的圖像數據,就需要將 Content-Type 設置爲 “image/jpg”;如果響應的內容(如Servlet的輸出內容)爲文本,
setContentType(String type)
方法用於設置字符編碼,如:“text/html;charset=UTF-8”(等同與調用response.setHeader(“content-type”, “text/html;charset=utf-8”)
)
5)setCharacterEncoding(String charset)
此方法用於設置輸出內容使用的字符集編碼,對 http 協議來說,就是設置 Content-Type 字段中的字符編碼部分。如果沒有設置 Content-Type 字段,
setCharacterEncoding(String charset)
方法設置的字符集編碼就不會出現在 http 響應頭消息中。另外,setCharacterEncoding(String charset)
的優先級高於setContentType(String type)
,它的設置結果將覆蓋setContentType(String type)
方法設置的字符集編碼
2.4 發送響應消息體相關方法
在響應消息中,ServletResponse(HttpServletResponse 的父接口)定義有兩個IO流輸出方法:
1)getOutputStream()
此方法所獲取的字節輸出流對象爲
ServletOutputStream
類型。ServletOutputStream
是OutputStream
的子類,它也可以直接輸出字節數組中的二進制數據(若想輸出二進制格式的響應正文,可以使用getOutputStream()
方法獲取 ServletOutputStream 對象),並通過write()
方法輸出。
2)getWriter()
正如 IO 流的字節輸出流和字符輸出流,ServletResponse 也定義有字符輸出流對象 PrintWriter,PrintWriter 類型的對象對應的獲取方法正是
getWriter()
,它可以直接獲取字符文本內容(若要輸出內容爲字符文本的響應正文,可以使用getWriter()
方法),並通過write()
方法輸出。
注:需要注意的是,getOutputStream()
方法和 getWriter()
方法不能同時使用,其原因是因爲調用 response.getWriter()
之前必須先調用 response.getOutputStream()
方法。
對於 request 、response 編碼時產生的亂碼,見 傳送門 !!!