1. 程式人生 > 實用技巧 >Servlet詳解(二)

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():獲取請求URLhttp://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)

    • 分兩個步驟:

      1. 先獲取流物件
      • BufferedReader getReader():獲取輸入字元流,只能操作字元資料
      • ServletInputStream getInputStream():獲取位元組輸入流,可以操作所有型別的資料(圖片啥的只能用位元組流來傳輸資料,而普通字元的話,都可以使用。在UTF-8編碼中,一箇中文字元佔3個位元組,在GBK中一箇中文字元佔2個位元組,所以用位元組流來傳輸資料要注意編碼格式)
      1. 在從流中獲取資料

        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編碼了。

有兩種方法:

  1. dfdf

  2. 我們在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種方式):

    1. forward:是指轉發,只包含一次請求,將當前request和response物件儲存,只能轉發到伺服器當前內部資源種(其他的Servlet物件),位址列的地址不會發生改變。

    2. redirect:是指重定向,包含兩次瀏覽器請求,瀏覽器根據url請求一個新的頁面,所有的業務處理都轉到下一個頁面,位址列的地址會變發生改變。

    3. include:意為包含,即包含url中的內容,進一步理解為,將url中的內容包含進當前的servlet當中來,並用當前servlet的request和respose來執行url中的內容處理業務.所以不會發生頁面的跳轉,位址列地址不會發生改變。


7. 共享資料

  • 域物件:一個擁有作用範圍的物件,可以在範圍內共享資料
  • request域:代表一次請求的範圍,一般用於請求轉發的多個資源中共享資料
  • 方法:
    • void setAttribute(String name,Object obj):儲存資料
    • Object getAttitude(String name):通過鍵獲取值
    • void removeAttribute(String name):通過鍵移除鍵值對