1. 写在开头的话
在Spring MVC中,若是在控制器方法返回的视图名称中,使用了redirect:
前缀,那么这个String就不再是用于查找视图了,即是用于让浏览器进行重定向的路径。当发生重定向了之后,之前的请求就会被作废,请求携带的数据也会被销毁,所以该如何保证数据在重定向时保持不变呢?(小知识点:如果使用forward:
前缀则表示转发,转发宽泛的说是同一个请求,不同的视图,所以数据不会被销毁)
如果你了解过会话技术的话,你就会觉得这不是一个难题,利用会话技术就可以解决这个问题了,so easy!
但是在这里我们并不讨论会话技术,讨论的是:
- 使用URL模板以路径变量和/或查询参数的形式传递数据;
- 通过flash属性发送数据
2.使用URL模板以路径变量和/或查询参数的形式传递数据
为了预防注入的危险,实际在开发过程中重定向不推荐如下写法:
return "redirect:/userinfo/"+user.getName();//除了注入的危险,这里还会存在,如果用户名为中文的时候,会乱码
而是采用占位符的方式:
model.addAttribute("username",user.getName());
return "redirect:/userinfo/{username}";
采用这种方式,不安全的字符会被转义,同时你还可以增加一些额外的参数:
model.addAttribute("username",user.getName());
model.addAttribute("age",user.getAge());
return "redirect:/userinfo/{username}";
如果增加的属性没有在URL中匹配到占位符,则会以查询参数的方式附加到路径中。
运行效果:
3.使用flash
Spring通过RedirectAttributes
来设置flash
,使用其的好处便是你不用管理该对象的销毁,因为flash
属性会一直携带这些数据到下一次请求,然后就消失,其实就是暂时将数据存到会话中,进行重定向之后,会从会话中取出这些数据,那么相应的会话就去掉这些数据了。
通过RedirectAttributes
提供一组addFlashAttribute()
方法来添加flash属性:
@RequestMapping(value = "/register",method = RequestMethod.POST)
public String processRegistration(User user, RedirectAttributes model) {
model.addFlashAttribute("user",user);
return "redirect:/userinfo";
}
@RequestMapping(value = "/userinfo",method = RequestMethod.GET)
public String showInfo(Model model){
return "userinfo";
}
html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<title>用户信息</title>
</head>
<body>
<h1 th:text="|${user.getName()}你好|"></h1>
</body>
</html>
运行结果:
tips:如果涉及到路径含有占位符,而占位符中的可能的字符包含中文,那么会出现重定向的地址(你在方法内返回的地址)和实际地址(重定向后浏览器的地址栏的地址)是不一样的,因为你返回的地址是被转义过了,比如:
/userinfo/%xx%xx%xx ==> 浏览器地址栏看到的是 /userinfo/张三
这个就会导致flash属性携带的值是交给了/userinfo/%xx%xx%xx 这个请求
而不是交给了 /userinfo/张三这个请求,最后就会导致你在处理这个请求时拿不到flash的值
尽管/userinfo/%xx%xx%xx转义是得到 /userinfo/张三
演示:
code:
@RequestMapping(value = "/register",method = RequestMethod.POST)
public String processRegistration(User user, RedirectAttributes model) {
model.addFlashAttribute("user",user);
model.addAttribute("username",user.getName());
return "redirect:/userinfo/{username}";
}
@RequestMapping(value = "/userinfo/{username}",method = RequestMethod.GET)
public String showInfo(@PathVariable String username,Model model){
return "userinfo";
}
本次分享就到这里了,如果你喜欢的话,记得给我点赞,谢谢!