Servlet詳解(二)
目錄
Request物件
1.request和response物件:
- request和response物件由tomcat伺服器來建立的,request將瀏覽器發來的請求封裝好給我們使用,response物件是我們來設定相應內容返回給瀏覽器的
2.request物件繼承體系結構:
(Tomcat幫我建立的是 org.apache.catalina.connector.RequestFacade類,我們在doGet,doPsot中一般用HttpServletRequest介面來獲取request(多型))
3.什麼是HttpServletRequest ?
HttpServletRequest 物件代表客戶端的請求,當客戶端通過HTTP協議訪問伺服器時,HTTP請求頭中的所有資訊都封裝在這個物件中,開發人員通過這個物件的方法,可以獲得客戶這些資訊。簡單來說,要得到瀏覽器傳送過來的資訊,就找HttpServletRequest物件
4.HttpServletRequest物件的常用方法:
-
4.1 獲取請求行的資料:
GET /test/demo?username=linzeliang&password=123456 HTTP/1.1
- String getMethod():獲取請求的方法
GET
- String getContextPath():獲取虛擬目錄
/test
- String getServletPath():獲取資源路徑
/demo
- String getQueryString():獲取GET請求方法的請求引數
username=linzeliang&password=123456
- String getRequestURI():獲取請求URI
/test/demo
(URI:統一資源識別符號) - StringBuffer getRequestURL():獲取請求URL
http://localhost/test/demo
(URL:統一資源定位符) - String getProtocol():獲取HTTP的協議與版本
HTTP/1.1
- String getRemoteAddr():獲取請求客戶主機的IP地址
127.0.0.1
-
4.2 獲取請求頭的資料(請求首部欄位):
- String getHeader(String name):通過首部欄位的名稱獲取對應的值
- Enumeration
getHeaderNames() :獲取所有首部欄位的名稱,封裝在Enumeration物件中,通過hasMoreElements()方法來判斷是否還有下一個元素,nextElement()方法用來獲取下一個元素名稱
-
4.3 獲取請求體資料(報文主體):
-
只有POST請求方式才有報文主題,GET請求方式沒有報文主體,只有報文首部和空行(\r\n)
-
分兩個步驟:
- 先獲取流物件
- BufferedReader getReader():獲取輸入字元流,只能操作字元資料
- ServletInputStream getInputStream():獲取位元組輸入流,可以操作所有型別的資料(圖片啥的只能用位元組流來傳輸資料,而普通字元的話,都可以使用。在UTF-8編碼中,一箇中文字元佔3個位元組,在GBK中一箇中文字元佔2個位元組,所以用位元組流來傳輸資料要注意編碼格式)
-
在從流中獲取資料
username=linzeliang&password=123456
-
-
4.4 獲取請求引數的通用方法
- 如果是get請求方法,引數名及值儲存在URI中,那麼可以通過引數名獲取值;如果是post方法,引數名及值是儲存在報文主體中的,那麼也可以通過引數名來獲取值、
- String getParameter(String name):通過引數名獲取值
- String[] getParameterValues(String name):通過引數名獲取值組成的陣列,通常是html中的checkbox複選框,一個引數名可以有多個值
- Enumeration<String[]> getParameterNames():獲取所有的引數名,封裝為Enumeration物件
- Map<String, String[]> getParameterMap():獲取所有的引數名稱及其對應的值(一個引數名對應值可以是多個)的Map集合
5.Request物件接收的引數是亂碼?
5.1 自從Tomcat5以來,GET方式和POST方式提交的請求,tomcat會採用不同的方式來處理編碼.在Tomcat8中,使用GET請求方法的亂碼問題已經解決了,但是,如果你用的是POST請求方法來獲取資料,那麼會得到亂碼,因為如果未設定編碼的話,則預設採用ISO-8859-1編碼。所以我們可以通過手動設定編碼來解決這個問題:
在doPost方法內部行先寫入這一個程式碼request.setCharacterEncoding("UTF-8")
,同理,如果要輸出到頁面,也應該先設定一下response的編碼response.setCharacterEncoding("UTF-8")
5.2 如果GET請求方式也出現亂碼了怎麼辦呢?
GET方式不同,它的資料是從訊息行帶過去的,沒有封裝到request物件裡面,所以使用request設定編碼是無效的。我們既然知道Tomcat預設的編碼是ISO 8859-1,那麼GET方式由訊息體帶過去給瀏覽器的時候肯定是用*ISO 8859-1編碼了。
有兩種方法:
-
dfdf
-
我們在Tomcat伺服器的配置下改成UTF-8的編碼,那麼就解決伺服器在解析資料的時候造成亂碼問題了,在8080埠的Connector上加入URIEncoding="UTF-8",設定Tomcat的訪問該埠時的編碼為UTF-8,從而解決亂碼,這種改法是固定使用UTF-8編碼的
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8"/>
6.請求轉發:
請求轉發:一種在伺服器內部的資源跳轉方式
-
通過request.getRequestDsipatcher(String path) 獲取請求轉發物件
-
然後通過這個RequestDispatcher物件來進行轉發(Servlet的請求轉發有3種方式):
-
forward:是指轉發,只包含一次請求,將當前request和response物件儲存,只能轉發到伺服器當前內部資源種(其他的Servlet物件),位址列的地址不會發生改變。
-
redirect:是指重定向,包含兩次瀏覽器請求,瀏覽器根據url請求一個新的頁面,所有的業務處理都轉到下一個頁面,位址列的地址會變發生改變。
-
include:意為包含,即包含url中的內容,進一步理解為,將url中的內容包含進當前的servlet當中來,並用當前servlet的request和respose來執行url中的內容處理業務.所以不會發生頁面的跳轉,位址列地址不會發生改變。
-
7. 共享資料
- 域物件:一個擁有作用範圍的物件,可以在範圍內共享資料
- request域:代表一次請求的範圍,一般用於請求轉發的多個資源中共享資料
- 方法:
- void setAttribute(String name,Object obj):儲存資料
- Object getAttitude(String name):通過鍵獲取值
- void removeAttribute(String name):通過鍵移除鍵值對