Spring MVC 控制器返回視圖名稱時,forward: 與 redirect: 前綴分別對應 Servlet 的 RequestDispatcher.forward() 與 HttpServletResponse.sendRedirect()。本文詳細對比兩者差異、適用場景與程式碼範例。
| 特性 | 請求轉發 | 重定向 |
|---|---|---|
| 語法 | return "forward:/path" | return "redirect:/path" |
| 底層 API | RequestDispatcher.forward() | HttpServletResponse.sendRedirect() |
| 請求次數 | 1 次(伺服器內部) | 2 次(瀏覽器發起新請求) |
| 瀏覽器地址欄 | 不變 | 變為新 URL |
| Request 域共享 | 是(同一 request) | 否(新 request) |
| 目標範圍 | 同一 Web 應用內部 | 任意 URL(跨應用、跨域名) |
| 路徑相對性 | 相對當前 Web App 根路徑 | 以 / 開頭相對站點根路徑 |
| 資料傳遞 | request.setAttribute() | 查詢字串、Session、Flash 屬性 |
| 刷新行為 | 重複提交表單風險 | 安全(GET 請求) |
@Controller
@RequestMapping("/users")
public class UserController {
// 轉發:內部跳轉,共享 request
@GetMapping("/query")
public String query(Model model) {
model.addAttribute("msg", "來自 query");
return "forward:/users/detail"; // 必須以 / 開頭
}
@GetMapping("/detail")
public String detail(Model model) {
// 可取得 query 設定的 msg
System.out.println(model.getAttribute("msg"));
return "user/detail";
}
// 重定向:瀏覽器跳轉,PRG 模式
@PostMapping("/save")
public String save(User user, RedirectAttributes ra) {
userService.save(user);
ra.addFlashAttribute("success", "儲存成功"); // Flash 屬性,僅下一次請求可用
return "redirect:/users/list"; // PRG:Post-Redirect-Get
}
@GetMapping("/list")
public String list() {
return "user/list";
}
// ModelAndView 寫法
@GetMapping("/mv")
public ModelAndView mvDemo() {
ModelAndView mv = new ModelAndView("forward:/users/detail");
// ModelAndView mv = new ModelAndView("redirect:/users/list");
return mv;
}
}
forward:/users/detail → 相對當前 Web App Context Path,等同 request.getRequestDispatcher("/users/detail")。redirect:/users/list → 相對站點根路徑,瀏覽器跳轉至 https://host:port/context/users/list。redirect:https://other.com/page → 絕對 URL,支援跨域跳轉。| 場景 | 推薦 | 理由 |
|---|---|---|
| 表單提交成功後 | redirect | 防止 F5 重複提交(PRG 模式) |
| 多步驟流程中間步驟 | forward | 共享 request 數據,避免 Session 污染 |
| 權限不足、登入攔截 | redirect | 改變 URL,讓用戶看到登入頁地址 |
| 跨應用跳轉 | redirect | forward 僅限同一容器內 |
| 錯誤頁面、異常處理 | forward | 保持原請求 URL,方便除錯 |
| 檔案下載、二維碼生成 | forward/直接輸出 | 視具體實作而定 |
RedirectAttributes.addFlashAttribute() 傳遞一次性數據。forward:users/detail(無 /)會相對當前請求路徑,易產生錯誤;習慣加 /。ERR_TOO_MANY_REDIRECTS。轉發是伺服器端行為,共享請求上下文,適用於內部流程控制;重定向是瀏覽器端行為,產生新請求,適用於表單提交後、跨應用、需改變 URL 的場景。掌握 PRG 模式與 RedirectAttributes 是 Spring MVC 開發必備技能。