轉發 重定向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