Spring MVC跨重定向请求传递数据
执行完post请求后,通常来讲一个最佳实践就是执行重定向。重定向将丢弃原始请求数据,原始请求中的模型数据和请求都会消亡。可以有效避免用户浏览器刷新或者后退等操作,直接间接地重复执行已经完成的post请求。
在控制方法中返回的视图名称中,在String前使用"redirect:"
前缀,那么这个String就不是来查找视图的,而是浏览器进行重定向的路径,相当于重新发出请求。
重定向通常相当于从一个controller
到另一个controller
。
如何使重定向发出的新请求携带数据?
一:拼接url路径
...
String path = "show";
String username=user.getName();
return "redirect:/"+path+"?username="+username;
....
@GetMapping("show")
public String show(){
return "show";
}
上面的例子有一个缺陷就是username中的不安全字符不会自动转义。Spring 3.1提供了解决方法:
@GetMapping("/hello")
public String hello(RedirectAttributes model){
model.addAttribute("path","show");
model.addAttribute("username","zhu");
return "redirect:/{path}";
}
@GetMapping("show")
public String show(){
return "show";
}
使用RedirectAttributes
模型添加属性。
path作为占位符添加到了路径中,RedirectAttributes
模型中的原始数据类型如username自动作为查询参数加到了url路径,并且所有的不安全字符都会转义。
Model的生命周期是一个请求,重定向是两个请求,我们不能使用原始的Model来跨请求传递数据。Spring 3.1引入了Model的一个子接口RedirectAttributes
,RedirectAttributes
提供了Model的所有功能,还添加了flash属性。
二:flash属性
url路径只能传递原始数据类型,并且数据是公开的。
如果我们想要传递对象或者将数据隐藏,就需要使用RedirectAttributes
模型的flash属性。
让我们探讨一下,假设没有flash属性,我们如何跨请求传递对象类型?
我们知道Model
模型数据是以请求参数的形式剪切到request
中的,重定向后请求就会丢失,模型数据也就完全丢失了。所以我们需要在重定向前将模型数据复制到session
中,并且在重定向后从session
中取出。
实际上这就是当我们向RedirectAttributes
模型添加flash属性时它为我们做的事。
RedirectAttributes
提供了一组addFlashAttribute()
方法来添加flash属
性。
我们在上面的例子中添加flash属性。
@GetMapping("/hello")
public String hello(RedirectAttributes model ){
model.addAttribute("path","show");
model.addAttribute("username","zhu");
/*添加flash属性*/
User user = new User();
user.setUsername("zhu");
user.setPassword("123456");
model.addFlashAttribute("user",user);
return "redirect:/{path}";
}
@GetMapping("show")
public String show(){
return "show";
}
show.html使用thymeleaf模板获取user对象,验证
<!DOCTYPE html >
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--<p th:text="${user.username}">123456</p>-->
<!--<p th:text="${hhh}">45789</p>-->
<p th:text="${user.username}"></p>
<p th:text="${user.password}"></p>
</body>
</html>
结果: