亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

Spring MVC 轉發與重定向

1. 前言

WEB 應用程序的交互模式通過請求包與響應包來完成,請求包一般由瀏覽器構建,并發送給服務器端。服務器端解析請求包,并根據具體的業務邏輯處理請求包中的數據,并構建響應包回應請求方。

響應包的實體部分中的內容可以由控制器的方法決定,或者說由需求來決定。根據響應包中的內容不同,可以分兩者響應方式:

  • 轉發:響應包直接包含響應給瀏覽器的數據;
  • 重定向:響應包僅包含數據視圖的地址。

本節課程將向大家講解 Spring MVC 中如何實現轉發和重定向。本章節的重點是了解轉發和重定向的本質。

2. 響應的本質

Spring MVC 項目中的用戶控制器用來處理用戶的請求,無論處理的結果如何,都需要給用戶一個響應,HTTP 響應包可以說是這個響應結果的載體。

理論上講,用戶控制器處理完請求,得到的結果數據可以直接寫入到響應包中。

@Controller
public class ResponseAction {
@RequestMapping("/response01")
public void response01(HttpServletResponse response) throws IOException {
	//發送給客戶端的響應數據
	String hello="hello";
	PrintWriter out =response.getWriter();
	out.write(hello);
	out.close();
}
}

把需要響應給客戶端的數據寫入響應包中便是響應的本質。

如果僅僅只是把數據發送給客戶端,數據在瀏覽器中顯示時,出來的樣式會過于簡單、甚至丑陋。要解決這個問題,也好辦,發送數據時,也附帶發送數據格式。

Tips:如果客戶端只需要純數據,如 JSON 格式,則可以直接使用上面的方法。

修改上面的響應數據:

String hello="<font color=\"red\">hello</font>";

這時,在瀏覽器中不僅能看到數據,還能用設計好的樣式顯示出來。初期 WEB 開發,便采用了這種 “數據 + 樣式” 的方式。因初期頁面中數據并不是很多,人為對于頁面無素顯示也沒有多大需求。

但是,隨著項目功能越來越大,數據量成倍增加,比如說商城首頁,需要顯示當前登錄者信息、商品信息、推薦的商品信息、用戶瀏覽信息…… 并且用戶對最終顯示結果也提出了更多要求,如美觀、大方、整潔……

如果還是如前面一樣,把數據和 HTML 一起編織在一起,然后響應給客戶端,代碼將變得丑陋不堪。

新的解決方案是采用組件化開發思想:控制器處理數據,視圖組件提供模板樣式用來顯示最終數據。

所以在構建響應包時,控制器需要 2 方面信息:

  • 數據:由控制器返回;
  • 視圖:由視圖解析器組件維護。

Spring MVC 提供數據模型組件充當數據和視圖之間的橋梁。

  • 控制器先把處理后的數據保存到數據模型中;
  • 找到視圖,由視圖從數據模型中取得數據,并顯示在視圖中。

重定向和轉發的區別在于尋找視圖的方式。

2.1 轉發

如下面的實例:

@RequestMapping("/response02")
public String response02(ModelMap model) throws IOException {
	//發送給客戶端的響應數據
	String hello="Hello";
	model.addAttribute("data", hello);
	return "hello";
}

上面代碼是一個典型的 Spring MVC 控制器代碼:

  • 變量 hello 中保存的就是要發送給瀏覽器的數據。
  • ModelMap 類型的數據模型可以說是一個中間載體,用來臨時保存 hello 中的數據;
  • return 后面的 “hello” 是視圖的邏輯名,由視圖解析器解析并找到真正的頁面。

下面是一個標準的視圖模板,頁面中已經提供了樣式,只等數據的到來。

  <html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Insert title here</title>
  </head>
  <body>
  <div style="color:red"> ${data} </div> 
  </body>
  </html>

有了這些信息后,視圖解析器把數據和視圖合二為一后進行渲染,得到純 HTML 后寫入響應包,發送給瀏覽器。

圖片描述

這便于轉發或者叫派發。默認情況下,控制器的響應方式使用的是轉發。

轉發是在一次請求中一氣呵成完成的。如上代碼,在瀏覽器輸入請求:http://localhost:8888/sm-demo/response02。

服務端響應包中的數據這就是響應給客戶端的最終數據。

Tips: Spring MVC 的整個請求和響應過程是由多個組件協作完成的,這里不深究細節。

2.2 重定向

Spring MVC 中使用重定向很簡單,只需要在返回值中添加 redirect 關鍵字。

@RequestMapping("/response03")
public String response03(ModelMap model) throws IOException {
	//發送給客戶端的響應數據
	String hello="Hello";
	model.addAttribute("data", hello);
	return "redirect:/hello";
}

重定向和轉發的本質區別在于如何找到視圖。轉發是控制器自己找的,也就是在服務器端找的。

重定向則是先把視圖地址寫入響應包,然后發送瀏覽器,意思是說,瀏覽器,麻煩你自己找一下。瀏覽器獲取到響應包中的地址后再發送一次請求,找到視圖,然后,把數據模型中的數據讀出來顯示在頁面中。

相比較轉發,重定向會多一次請求,也意味著數據模型中的數據需要在跨請求間被解析到。另外,視圖文件必須放置在瀏覽器能訪問到的位置。如果視圖文件放在 WEB-INF 目錄下,則重定向是不能訪問到的。

圖片描述

3. 小結

本章節和大家一起講解 Spring MVC 框架如何實現轉發和重定向,從實現角度來講,沒有太多難度。默認情況下就是轉發,加上 redirect 關鍵字后就能實現重定向。需要注意的是,redirect 后面需要指定視圖文件的完整路徑。

轉發和重定向都是一種響應方式,其內在區別就在于一個是尋找視圖的方式是不同的。一個是控制器幫著找,一個是瀏覽器通過再次發起請求尋找,所以,重定向和轉發對數據模型的作用域要求是不同的。