Spring MVC 轉發和重定向


本文介紹Spring MVC中轉發和重定向的區別。

轉發和重定向

 開始Java EE時,可能會對轉發(forward)和重定向(redirect)這個兩個概念不清楚。本文先通過代碼實例和運行結果圖片感性 認識二者的區別,然后給出二者的定義。

1、常規用法,返回一個View

@RequestMapping(value="/testa", method=RequestMethod.GET)
public String inputData(){
    return "testa"; //Spring框架找到對應的View並渲染
}

@RequestMapping(value="/testa", method=RequestMethod.POST)
public String outputData(HttpServletRequest request){
    String userName = request.getParameter("name");
    String password = request.getParameter("pwd");
    request.setAttribute("name", userName);
    request.setAttribute("pwd", password);
    return "testb"; //Spring框架找到對應的View並渲染
 }
   
   
  
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

打開testa網頁:

輸入用戶名:spring,密碼:spring:

這里寫圖片描述

點擊登陸按鈕,頁面變為如下:

這里寫圖片描述

再次刷新,谷歌瀏覽器提示重新提交表單。

這里寫圖片描述

對比圖片,發現瀏覽器的輸入框中URL不變,但是不同情況下顯示不同的View。跳轉時Model共享(表單會被重復提交)。

2、轉發(forward)

@RequestMapping(value="/testa", method=RequestMethod.GET)
public String inputData(){
    return "testa"; //Spring框架找到對應的View並渲染
}

@RequestMapping(value="/testa", method=RequestMethod.POST)
public String outputData(HttpServletRequest request){
    String userName = request.getParameter("name");
    String password = request.getParameter("pwd");
    request.setAttribute("name", userName);
    request.setAttribute("pwd", password);
    //轉發到 /testb 的Controller方法(即outputDataX)上
    return "forward:/testb"; 
}

@RequestMapping(value="/testb", method=RequestMethod.POST)
public String outputDataX(HttpServletRequest request){
    return "testb";
}
   
   
  
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

打開testa網頁:

輸入用戶名:spring,密碼:spring:

這里寫圖片描述

點擊登陸按鈕,頁面變為如下:

這里寫圖片描述

調試分析:forward后面跟一個資源。當程序運行到return “forward:/testb”時,會執行會執行該資源對應的方法outputDataX。
另外轉發時,瀏覽器的URL不變。

再次刷新,谷歌瀏覽器提示重新提交表單。

這里寫圖片描述

3、重定向(redirect)

@RequestMapping(value="/testa", method=RequestMethod.GET)
public String inputData(){
    return "testa"; //Spring框架找到對應的View並渲染
}

@RequestMapping(value="/testa", method=RequestMethod.POST)
public String outputData(HttpServletRequest request){
    String userName = request.getParameter("name");
    String password = request.getParameter("pwd");
    request.setAttribute("name", userName);
    request.setAttribute("pwd", password);
    //重定向到 /testb 的Controller方法(即outputDataY)上
    return "redirect:/testb"; 
}

@RequestMapping(value="/testb", method=RequestMethod.POST)
public String outputDataX(HttpServletRequest request){
    return "testb";
}

@RequestMapping(value="/testb", method=RequestMethod.GET)
public String outputDataY(HttpServletRequest request){
    return "testb";
}
   
   
  
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

打開testa網頁:

輸入用戶名:spring,密碼:spring:

這里寫圖片描述

點擊登陸按鈕,頁面變為如下:

這里寫圖片描述

調試分析:redirect后面跟一個資源。當執行到return “redirect:/testb”時,會執行該資源對應個方法outputDataY。由於重定向Model不共享,所以頁面無數據顯示。
另外重定向后瀏覽器的輸入框中URL也發生變化。

刷新后,谷歌瀏覽器沒有提示重新提交表單

這里寫圖片描述

總結:
常說的可以通過redirect: URL防止重復提交表單,就是上面過程的意思。
原理是對於redirect而言,Request的attribute不會被傳遞,放到session中,session在跳到頁面后馬上移除對象。所以你刷新一下后這個值就會丟掉。

如果你希望Request的attribute被傳遞,可以使用RedirectAttributes類。

@RequestMapping(value="/testa", method=RequestMethod.GET)
 public String inputData(){
  return "testa"; //Spring框架找到對應的View並渲染
 }

 @RequestMapping(value="/testa", method=RequestMethod.POST)
 public String outputData(HttpServletRequest request, RedirectAttributes redirectAttributes){
  String userName = request.getParameter("name");
  String password = request.getParameter("pwd");
  request.setAttribute("name", userName);
  request.setAttribute("pwd", password);
  //重定向到 /testb 的Controller方法(即outputDataY)上
  //重定向傳遞參數的兩種方法
  redirectAttributes.addAttribute("name", userName);
  redirectAttributes.addFlashAttribute("pwd", password);

  return "redirect:/testb"; 
 }

 @RequestMapping(value="/testb", method=RequestMethod.POST)
 public String outputDataX(HttpServletRequest request){
  return "testb";
 }

 @RequestMapping(value="/testb", method=RequestMethod.GET)
 public String outputDataY(HttpServletRequest request){
  String userName = request.getParameter("name");
  request.setAttribute("name", userName);
  return "testb";
 }

   
   
  
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

運行如下:

這里寫圖片描述

上面示例了使用RedirectAttributes傳遞參數的兩種方法:
1. 使用RedirectAttributes類的addAttribute方法傳遞參數會跟隨在URL后面,如上圖谷歌瀏覽器所示,URL為http://localhost:8080/testb?name=spring
2. 使用RedirectAttributes類的addFlashAttribute方法傳遞參數不會跟隨在URL后面,會把該參數值暫時保存於session,待重定向URL獲取該參數后從session中移除,這里的redirect必須是方法映射路徑,jsp無效。你會發現redirect后的jsp頁面中pwd只會出現一次,刷新后pwd再也不會出現了。下圖為刷新后的結果,密碼pwd顯示為空。這驗證了上面說的,pwd在被訪問后就會從session中移除。對於防止重復提交可以使用此方法。

定義

作為一個經驗豐富的servlet/JSP程序員,必須知道轉發和重定向的區別。 轉發比重定向快,因為重定向經過客服端,而轉發沒有。但是,又是采用重定向更好,若需要重定向到一個外部網站,則無法使用轉發。

個人理解:好比服務器窗口A點餐,窗口B取餐。轉發就是瀏覽器到服務器窗口A點餐,點完餐后,服務器內部從窗口B取餐,把飯菜直接給瀏覽器。重定向就是瀏覽器到服務器窗口A點餐,服務器不幫助瀏覽器從窗口B取餐,而是告知瀏覽器到B取餐。瀏覽器得到信息后再向窗口B發出取餐要求。

返回 Java EE Web開發系列導航


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM