1. 程式人生 > >轉發 重定向HttpServletRequest & HttpServletResponse

轉發 重定向HttpServletRequest & HttpServletResponse

Servlet的實現和相關的方法

一、HttpServletRequest類

HttpServletRequest類封裝了從客戶端傳遞過來的資訊。

每次請求,Tomcat都會建立一個HttpServletRequest物件例項傳遞到service請求的方法中。

public void service(ServletRequest request, ServletResponse response);

《1》Request物件常用方法

getRequestURI()             獲取請求的資源路徑
getRequestURL()             獲取請求的統一資源定位符
getRemoteHost()             獲取請求的客戶端ip地址
getHeader()                 獲取請求頭資訊
getParameter()              獲取請求引數值(只能獲取請求引數的一個值)
getParameterValues()        獲取請求的多個值(常用於複選框和下拉列表多選)。
getRequestDispatcher()      獲取請求的轉發物件。轉發請求(轉發的請求和原請求共享request物件和response物件)
getMethod()                 獲取請求的方式GET 或 POST

setAttribute(key, value);   設定Request請求範圍的屬性值。
getAttribute(key);              獲取Request請求範圍的屬性值。

ServletContext              是域物件(域的範圍是整個web工程)

Request也是域物件之一 (是在同一個請求內)

getCookies()            獲取Cook物件
getSession()            獲取或建立Session物件

《2》獲取請求行

request.getRequestURI();    獲取請求的資源路徑   /day07/requst1  表示訪問的是day07工程下的/request1的servlet動態資源
request.getRequestURL();獲取請求的統一資源定位符。
http://192.168.11.30:8080/day07/request1
192.168.11.30 是我的ip地址
8080 伺服器埠號
day07是工程名
request1 是資源的路徑

獲取請求的資源路徑:

System.out.println( "getRequestURI==>>" + request.getRequestURI() );
// 獲取請求路徑的統一資源定位符
System.out.println( "getRequestURL==>>" + request.getRequestURL() );

圖8
這裡寫圖片描述
2) 獲取訪問的客戶端的ip地址:

    // 獲取客戶端的ip地址
    System.out.println("getRemoteHost==>>" + request.getRemoteHost());

得到客戶端的請求ip地址 例如:192.168.11.10 , 192.168.10.32等等

3) 獲取請求頭資訊

    //獲取請求頭的資訊。
    System.out.println("getHeader('User-Agent')==>>" + request.getHeader("User-Agent"));

列印內容(不同的瀏覽器,得到的資訊不一樣):
getHeader('User-Agent')==>>Mozilla/5.0 (Windows NT 6.1; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0

(二)獲取請求引數的值★★★

《1》表單如下:

<form action="http://127.0.0.1:8080/day07/params" method="get">
        使用者名稱:<input name="username" type="text" /><br/>
        密 碼:<input name="password" type="password" /><br/>
        興趣愛好:
            <input name="hobby" type="checkbox" value="c" />C
            <input name="hobby" type="checkbox" value="cpp" />C++
            <input name="hobby" type="checkbox" value="java" />java
            <input name="hobby" type="checkbox" value="php" />php
            <br/>
        <input type="submit" />
</form>

2) 接收請求引數的程式碼:

public class Params extends HttpServlet {

private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    //獲取客戶端傳遞過來的使用者名稱引數值
    String username = request.getParameter("username");
    System.out.println("使用者名稱:" + username);

    // 獲取密碼
    String password = request.getParameter("password");
    System.out.println("密碼:" + password);

-----------------------------------------------------------------------
    // 獲取興趣愛好,這個方法只能獲取到一個興趣愛好。
    //      String hobby = request.getParameter("hobby");
    //      System.out.println("getParameter得到的興趣愛好:" + hobby);


    // 如果獲取的引數有多個值的情況下。我們都使用getParameterValues方法來獲取
    // 因為它可以獲取到多個值。而getParameter只能獲取到一個值。
    String[] hobbys = request.getParameterValues("hobby");
    if (hobbys != null) {
        for (String hb : hobbys) {
            System.out.println("getParameterValues興趣愛好:"  + hb);
        }
    }
}

圖片9

這裡寫圖片描述

《2》做為域物件設定請求Request範圍的屬性值

把下面的這三行程式碼放到任意一個Servlet中,去請求訪問。

    // 在Request中設定 屬性值。
    request.setAttribute("abc", "abcValue");

    // 獲取 Request域中的屬性值
    String abcAttr = (String) request.getAttribute("abc");
    System.out.println(abcAttr); // 控制檯列印 abcValue

如果大家讀原始碼你會發現。其實在Request物件中,有一個Map物件用來存放 屬性值。

所以屬性的操作就跟操作一個map物件是一樣的。

☆☆二、請求轉發

1)問題:什麼是請求的轉發?

請求的轉發主要用在把Servlet中的資料轉發到Jsp中去顯示
jsp是一個Servlet程式

如圖

圖10
這裡寫圖片描述

2)請求轉發的具體實現程式碼:

從Servlet1轉發到Servlet2

Servlet1實現如下:

圖11
這裡寫圖片描述
Servlet2實現如下:

4) 控制檯列印如下內容:

這裡寫圖片描述
請求轉的的小結:

比如Servlet1把請求轉發給Servlet2

1.首先Servlet1和Servlet2中request和response物件是同一個物件。

2.在Servlet1,中和Servlet2都可以獲取到相同的請求的引數值,
並且也可以獲取到相同屬性值

3.轉發的時候,瀏覽器位址列的地址不發會生變化

5)、Base標籤轉發中的相對路徑

base 標籤它會把所有的相對路徑,設定在base指定的路徑的基礎之上做操作。

圖14

這裡寫圖片描述

三、HttpServletResponse類

Response物件封裝了伺服器到客戶端返回的資訊。

1)、獲取輸出流

getOutoutStream() 拿到的是二進位制流。

主要用於返回二進位制資料。比如說下載,圖片驗證碼等。

getWriter() 拿到字元流。大部分的返回都用writer。

這兩個輸出流,我們不能同時獲取兩個,只能使用一個做為返回。

只要同時獲取兩個輸出流就會報錯,不管你是先獲取二進位制輸出,還是先獲取字串輸出流。

程式碼如下:

/**
 * 同時通過response物件獲取兩個輸出流物件,就會報錯。
 * 不管你是先獲取二進位制的位元組流,還是字元流
 */
protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    // 獲取二進位制輸出流
    response.getOutputStream();
    // 獲取字串輸出流
    response.getWriter();

}

圖15
這裡寫圖片描述
2)、輸出字串內容到客戶端

往客戶端輸出。分兩個步驟:

第一步:先獲取輸出流(二進位制返回用獲取位元組流,字元出獲取字元流)

第二步:呼叫輸出流物件,寫出資料第客戶端

如:

protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    // 通過response響應物件獲取到字元輸出流
    Writer writer = response.getWriter();
    // 往 客戶 端 輸出資料。
    writer.write("this is response content!");
}

3)設定響應狀態碼,和設定響應頭

protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    /**
     * 當響應狀態碼為302的時候,表示要重定義。
     * 瀏覽器會檢測Location的值,去重新發起請求。
     */
    // 設定響應狀態碼 302 表示重定向
    response.setStatus(302);
    // 設定響應頭 Location中的資訊
    // 瀏覽器會把Location中的值重新發起一次請求。
    //  response.setHeader("Location", "http://127.0.0.1:8080/day07/response2");
    // 瀏覽器會重新 發起請求http://www.baidu.com
    response.setHeader("Location", "http://www.baidu.com");
}

2)在瀏覽器中訪問響應狀態的程式碼。得到的響應內容如下:

圖16
這裡寫圖片描述
並且瀏覽器收到響應後會馬上自動發生起第二次的請求。

第二次請求的地址是Location對應的值。

總結重定向:

請求重定向。是兩次請求,瀏覽器位址列會發生改變。

第一次請求返回的響應碼為302.並且有響應頭Location的內容。

第二次請求的地址就是Location對應的值。

重定向,第二次請求不僅可以是站內的資源,也可以是站外的資源。

4.5、請求重定向 sendRedirect的方式

除了通過設定響應狀態碼和響應頭可以實現重定向之外。

我們還可以通過HttpServletResponse物件的sendRedirect方法實現重定向。
這裡寫圖片描述
程式碼如:

    protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    /**
     * 當響應狀態碼為302的時候,表示要重定向。
     * 瀏覽器會檢測Location的值,去重新發起請求。
     */
    // 設定響應狀態碼 302 表示重定向
//      response.setStatus(302);
    // 設定響應頭 Location中的資訊
    // 瀏覽器會把Location中的值重新發起一次請求。
    //  response.setHeader("Location", "http://127.0.0.1:8080/day07/response2");
    // 瀏覽器會重新 發起請求http://www.baidu.com
//      response.setHeader("Location", "http://www.baidu.com");

    //方式二、、 通過sendRedirect方法直接重定向到你需要的網址。
    response.sendRedirect("http://www.baidu.com");
}

第二次是訪問Location中的地址。

最後:請求轉發和重定向的對比

圖18
這裡寫圖片描述