
Spring MVC 重定向(Redirect)详解
1. 核心概念与作用
重定向(Redirect) 是 Spring MVC 中一种客户端重定向机制,通过 HTTP 302 状态码(默认)将用户浏览器重定向到指定 URL。
- 主要用途 :
- 防止表单重复提交(提交后跳转到新页面)。
- 实现页面跳转(如登录成功后跳转到主页)。
- URL 重写或简化(如将
/old-path
重定向到/new-path
)。
2. 基本使用方式
2.1 通过返回值直接重定向
在控制器方法中直接返回 redirect:URL
格式的字符串:
java
@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 中追加查询参数
java
@GetMapping("/search")
public String search(@RequestParam String query) {
return "redirect:/results?query=" + query; // 原始方式
}
3.2 使用占位符语法(推荐)
Spring 提供模板化的参数注入:
java
@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 基本用法
java
@PostMapping("/submit")
public String submitForm(@ModelAttribute FormData data, RedirectAttributes attributes) {
// 存储数据到 Flash Scope
attributes.addAttribute("message", "提交成功");
attributes.addFlashAttribute("user", data.getUser());
return "redirect:/confirmation";
}
4.2 在目标页面获取数据
java
@GetMapping("/confirmation")
public String showConfirmation(@ModelAttribute("user") User user,
@RequestParam("message") String message) {
// 处理数据
return "confirmation";
}
5. 使用 RedirectView
对象
通过返回 RedirectView
对象实现重定向,提供更多控制选项:
java
@GetMapping("/custom-redirect")
public RedirectView customRedirect() {
RedirectView redirectView = new RedirectView("/home", true); // 第二个参数:是否重写 URL
redirectView.setUrl("/home?param=value");
return redirectView;
}
6. 与转发(Forward)的区别
对比项 | 重定向(Redirect) | 转发(Forward) |
---|---|---|
请求次数 | 生成新的 HTTP 请求(客户端发起) | 单次请求,服务器内部跳转 |
URL 变化 | 浏览器地址栏显示新 URL | 地址栏 URL 保持不变 |
数据传递 | 需通过 URL 参数或 Flash Scope | 可直接传递模型数据(Model ) |
适用场景 | 防重复提交、跨控制器跳转 | 内部页面跳转(如模块间协作) |
7. 完整代码示例
7.1 基础重定向
java
@Controller
public class RedirectController {
@GetMapping("/login")
public String login() {
// 直接重定向到主页
return "redirect:/home";
}
@GetMapping("/home")
public String home() {
return "home"; // 返回视图名称
}
}
7.2 带参数的重定向
java
@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
java
@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()
编码参数:javaString encodedQuery = URLEncoder.encode(query, StandardCharsets.UTF_8); return "redirect:/results?query=" + encodedQuery;
Q2:如何修改重定向的 HTTP 状态码(如 301)?
-
默认:Spring 使用 302 临时重定向。
-
自定义状态码 :需结合
ResponseEntity
:java@GetMapping("/permanent-redirect") public ResponseEntity<?> permanentRedirect() { return ResponseEntity.status(301).location(URI.create("/new-url")).build(); }
Q3:RedirectAttributes
的数据在目标页面不可见?
-
原因 :未使用
addFlashAttribute()
,而是直接addAttribute()
。 -
修正 :
javaattributes.addFlashAttribute("user", user); // 使用 addFlashAttribute()
9. 总结表格:重定向方法对比
方法类型 | 实现方式 | 参数传递能力 | 适用场景 |
---|---|---|---|
返回字符串 | return "redirect:/url" |
简单参数 | 基础重定向 |
RedirectView | 返回 RedirectView 对象 |
高度灵活 | 需自定义重定向逻辑 |
RedirectAttributes | 通过 addFlashAttribute() |
复杂对象 | 需传递模型数据到重定向页面 |
总结
Spring MVC 的重定向机制通过 redirect:
前缀和 RedirectAttributes
等工具,提供了灵活的跳转能力。核心是理解客户端重定向与服务器转发的区别,以及如何安全地传递数据。实际开发中,推荐使用 RedirectAttributes
处理复杂数据,避免手动拼接 URL 参数可能带来的安全风险(如 XSS 攻击)。