Spring MVC 重定向(Redirect)詳解
1. 核心概念與作用
重定向(Redirect) 是 Spring MVC 中一種客戶端重定向機制,通過 HTTP 302 狀態碼(默認)將用戶瀏覽器重定向到指定 URL。
- 主要用途:
- 防止表單重復提交(提交后跳轉到新頁面)。
- 實現頁面跳轉(如登錄成功后跳轉到主頁)。
- URL 重寫或簡化(如將
/old-path
重定向到/new-path
)。
2. 基本使用方式
2.1 通過返回值直接重定向
在控制器方法中直接返回 redirect:URL
格式的字符串:
@GetMapping("/login")
public String loginSuccess() {// 登錄成功后重定向到主頁return "redirect:/home";
}
2.2 指定重定向 URL 路徑
- 絕對路徑:
redirect:/home
- 相對路徑:
redirect:../another-page
(不推薦,易出錯) - 外部 URL:
redirect:https://example.com
(需謹慎使用)。
3. 傳遞參數到重定向目標
3.1 在 URL 中追加查詢參數
@GetMapping("/search")
public String search(@RequestParam String query) {return "redirect:/results?query=" + query; // 原始方式
}
3.2 使用占位符語法(推薦)
Spring 提供模板化的參數注入:
@GetMapping("/search")
public String search(@RequestParam String query) {// 使用占位符 {query} 自動替換return "redirect:/results?query={query}".replace("{query}", query);
}
// 或更簡潔的寫法:
return "redirect:/results?query=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
4. 通過 RedirectAttributes
傳遞數據
RedirectAttributes
是 Spring 提供的專門用于重定向時傳遞數據的接口,數據會通過 Flash Scope 存儲(在重定向請求中有效)。
4.1 基本用法
@PostMapping("/submit")
public String submitForm(@ModelAttribute FormData data, RedirectAttributes attributes) {// 存儲數據到 Flash Scopeattributes.addAttribute("message", "提交成功");attributes.addFlashAttribute("user", data.getUser());return "redirect:/confirmation";
}
4.2 在目標頁面獲取數據
@GetMapping("/confirmation")
public String showConfirmation(@ModelAttribute("user") User user,@RequestParam("message") String message) {// 處理數據return "confirmation";
}
5. 使用 RedirectView
對象
通過返回 RedirectView
對象實現重定向,提供更多控制選項:
@GetMapping("/custom-redirect")
public RedirectView customRedirect() {RedirectView redirectView = new RedirectView("/home", true); // 第二個參數:是否重寫 URLredirectView.setUrl("/home?param=value");return redirectView;
}
6. 與轉發(Forward)的區別
對比項 | 重定向(Redirect) | 轉發(Forward) |
---|---|---|
請求次數 | 生成新的 HTTP 請求(客戶端發起) | 單次請求,服務器內部跳轉 |
URL 變化 | 瀏覽器地址欄顯示新 URL | 地址欄 URL 保持不變 |
數據傳遞 | 需通過 URL 參數或 Flash Scope | 可直接傳遞模型數據(Model ) |
適用場景 | 防重復提交、跨控制器跳轉 | 內部頁面跳轉(如模塊間協作) |
7. 完整代碼示例
7.1 基礎重定向
@Controller
public class RedirectController {@GetMapping("/login")public String login() {// 直接重定向到主頁return "redirect:/home";}@GetMapping("/home")public String home() {return "home"; // 返回視圖名稱}
}
7.2 帶參數的重定向
@GetMapping("/search")
public String search(@RequestParam String query) {// 將查詢參數傳遞到 results 頁面return "redirect:/results?query=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}@GetMapping("/results")
public String results(@RequestParam String query, Model model) {model.addAttribute("query", query);return "results";
}
7.3 使用 RedirectAttributes
@PostMapping("/submit")
public String submitForm(@ModelAttribute FormData data, RedirectAttributes attributes) {attributes.addFlashAttribute("successMessage", "提交成功");return "redirect:/thank-you";
}@GetMapping("/thank-you")
public String thankYou(@ModelAttribute("successMessage") String message, Model model) {model.addAttribute("message", message);return "thank-you";
}
8. 常見問題與解決方案
Q1:重定向后參數丟失?
- 原因:未正確編碼特殊字符(如空格、中文)。
- 解決:使用
URLEncoder.encode()
編碼參數:String encodedQuery = URLEncoder.encode(query, StandardCharsets.UTF_8); return "redirect:/results?query=" + encodedQuery;
Q2:如何修改重定向的 HTTP 狀態碼(如 301)?
- 默認:Spring 使用 302 臨時重定向。
- 自定義狀態碼:需結合
ResponseEntity
:@GetMapping("/permanent-redirect") public ResponseEntity<?> permanentRedirect() {return ResponseEntity.status(301).location(URI.create("/new-url")).build(); }
Q3:RedirectAttributes
的數據在目標頁面不可見?
- 原因:未使用
addFlashAttribute()
,而是直接addAttribute()
。 - 修正:
attributes.addFlashAttribute("user", user); // 使用 addFlashAttribute()
9. 總結表格:重定向方法對比
方法類型 | 實現方式 | 參數傳遞能力 | 適用場景 |
---|---|---|---|
返回字符串 | return "redirect:/url" | 簡單參數 | 基礎重定向 |
RedirectView | 返回 RedirectView 對象 | 高度靈活 | 需自定義重定向邏輯 |
RedirectAttributes | 通過 addFlashAttribute() | 復雜對象 | 需傳遞模型數據到重定向頁面 |
總結
Spring MVC 的重定向機制通過 redirect:
前綴和 RedirectAttributes
等工具,提供了靈活的跳轉能力。核心是理解客戶端重定向與服務器轉發的區別,以及如何安全地傳遞數據。實際開發中,推薦使用 RedirectAttributes
處理復雜數據,避免手動拼接 URL 參數可能帶來的安全風險(如 XSS 攻擊)。