
在 Spring Boot 中,通过 return "redirect:..." 进行重定向时,普通 Model 中添加的属性无法传递到目标控制器方法,必须使用 RedirectAttributes 的 addFlashAttribute() 才能实现跨重定向的数据暂存。
在 spring boot 中,通过 return "redirect:..." 进行重定向时,普通 model 中添加的属性无法传递到目标控制器方法,必须使用 redirectattributes 的 addflashattribute() 才能实现跨重定向的数据暂存。
当控制器方法返回重定向(如 "redirect:/getAccountFragment")时,Spring MVC 会发起一次新的 HTTP GET 请求,原始请求作用域内的 Model 对象随之销毁——这意味着通过 model.addAttribute() 添加的属性不会自动携带至重定向后的请求中。这是设计使然,并非 Bug,目的是避免状态污染和重复提交风险。
正确做法是使用 RedirectAttributes 接口(通常作为控制器方法参数注入),调用其 addFlashAttribute(String attributeName, Object attributeValue) 方法。该方法将属性以“闪存属性”(Flash Attribute)形式存储在 HttpSession 中(默认),并在下一次请求开始时自动复制到目标处理器的 Model 中,随后立即清除,确保一次性、安全地传递数据。
以下是修正后的完整示例:
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String doLogin(
@RequestParam("username") String username,
@RequestParam("password") String password,
RedirectAttributes redirectAttributes) throws IOException {
boolean logged = elasticSearchConnector.checkCredentials(username, password, context);
// ✅ 使用 RedirectAttributes 替代 Model 存储重定向所需数据
redirectAttributes.addFlashAttribute("logged", logged);
if (logged) {
redirectAttributes.addFlashAttribute("username", username); // ✅ 正确传递 username
return "redirect:/getAccountFragment";
} else {
// ❌ 注意:此处不能用 redirectAttributes 传 loginError(因不重定向),应继续用 Model 或视图逻辑处理
return String.format("fragments/login-fragment :: content(url='%s')", "/?lang=en");
}
}
@RequestMapping(value = "/getAccountFragment", method = RequestMethod.GET)
public String getAccountFragment(Model model) throws IOException, ParseException {
// ✅ 闪存属性已自动注入 model,可直接访问
if (!model.containsAttribute("logged") || !(boolean) model.getAttribute("logged")) {
return String.format("fragments/login-fragment :: content(url='%s')", "/?lang=en");
}
String username = (String) model.getAttribute("username"); // ✅ 现在不再为 null
System.out.println("Username from flash: " + username); // 输出:amedeo
// 后续业务逻辑...
return "fragments/account-fragment";
}
⚠️ 关键注意事项:
-
RedirectAttributes仅对重定向生效;普通视图渲染(如返回 Thymeleaf 模板路径)仍应使用Model。 -
addFlashAttribute()是唯一支持跨重定向传递对象的方式;addAttribute()或model.addAttribute()在重定向场景下无效。 - 闪存属性默认依赖
HttpSession,若禁用 session(如无状态微服务),需配置FlashMapManager或改用 URL 参数(如redirect:/path?username=xxx,但仅适用于简单、非敏感数据)。 - 不要在重定向后的方法中再次调用
redirectAttributes.addFlashAttribute(),除非你明确需要向下一次重定向传递数据。
掌握 RedirectAttributes 的正确用法,是构建健壮、符合 REST 原则的 Spring Boot Web 应用的关键一环。











