Spring MVC 重定向传递数据
1. 前言
本节课程和大家一起讲解 Spring MVC 框架是如何跨请求传递数据的,让数据在重定向期间能被读出来。你需要重点掌握对 RedirectAttributes 组件的使用。
2. 查询字符串
如果是转发,数据模型只需要是请求作用域级别的,视图解析器便能从数据模型中拿到所需要的数据。对于重定向,因为跨了请求,视图无法读出请求作用域级别的数据模型中的数据。
如果要让数据模型中的数据被视图识别出来,则需要提升数据模型的作用域,如升级为会话作用域级别。所谓会话作用域,意味着数据会存放在服务器的会话缓存区。如果数据使用的频率不是很高,会产生空间上的浪费。
有没有一种较佳的方案,即不浪费服务器空间,又能传递数据了?
答案是肯定的。最原始的方式便是采用查询字符串的方式。
如下面的实例:
@RequestMapping("/response03")
public String response03(ModelMap model) throws IOException {
// 发送给客户端的响应数据
String hello = "Hello";
model.addAttribute("data", hello);
return "redirect:/hello.jsp";
}
model 中的数据只是请求作用域级别,重定向后的 hello.jsp 中无法获取此数据, Spring MVC 内部处理方式是把数据附加在 hello.jsp 后面。
打开浏览器,输入请求 http://localhost:8888/sm-demo/response03 地址,查看浏览器的地址栏中的 URL 变成 http://localhost:8888/sm-demo/hello.jsp?data=Hello。
Tips:数据附加在 URL 后面是 Spring MVC 自动完成的。
把 hello.jsp 页面中的数据读取方式改成下面的方式(从查询参数中读取)。
<div style="color:red">${param.data} </div>
这种方式有 2 个缺点:
-
安全性低,数据赤裸裸地暴露在地址栏中;
-
如果数据量多,则整个 URL 变得臃肿不易维护。
多数据实例:
@RequestMapping("/response03")
public String response03(ModelMap model) throws IOException {
// 发送给客户端的响应数据
String hello = "Hello";
model.addAttribute("data", hello);
model.addAttribute("id", 1);
return "redirect:/hello.jsp";
}
当请求后,URL 会变成 http://localhost:8888/sm-demo/hello.jsp?data=Hello&id=1 。
3. 模板方式
Spring MVC 提供有一种所谓的模板方法,和前面的以查询字符串方法进行附加没有多大区别。如下面的代码,数据模型中的 data 对应数据会以 URL 变量方式传递。数据模型中其它数据则以查询字符串方式进行传递。
@RequestMapping("/response04")
public String response04(ModelMap model) throws IOException {
// 发送给客户端的响应数据
String hello = "Hello";
model.addAttribute("data", hello);
model.addAttribute("id", 1);
return "redirect:/test/{data}";
}
@RequestMapping("/test/{data}")
public String response05(@PathVariable("data") String data,@RequestParam("id") int id)
throws IOException {
System.out.println(data);
System.out.println(id);
return null;
}
当在浏览器中请求 http://localhost:8888/sm-demo/response04 后,浏览器的地址栏中会变成 :http://localhost:8888/sm-demo/test/Hello?id=1。
模板方式其本质和查询字符串没有太多区别。
4. 使用 Flash 属性
Spring MVC 使用重定向时,内部会做些处理,把数据以查询字符串或变量参数方式进行传递。对于简单的数据传递已经足够了。如果需要传递一个对象,则需要把一个对象拆分后再传递,显然不是一种最佳方案。
Spring MVC 提供有 RedirectAttributes 组件,专用于重定向期间进行数据传递,其本质是把数据先保存在会话作用域中,但不会长时间占据会话存储空间,当整个重定向结束后数据会自动从会话作用域中删除。
所以,RedirectAttributes 组件中的属性也叫 Flash 属性。
如下面实例:用户对象以 Flash 属性的方式封装在模型对象中进行传递。
@RequestMapping("/response05")
public String response06(RedirectAttributes model) throws IOException {
User user=new User("mk", "123");
model.addFlashAttribute("user", user);
return "redirect:/test01";
}
Tips:重定向路径 test01 是控制器中的另一个方法,如下所示。
@RequestMapping("/test01")
public String response07(ModelMap model)
throws IOException {
User user= (User) model.get("user");
System.out.println(user);
return "hello";
}
自然,在 hello 视图中很便捷的就能得到数据。
<body>
<div style="color:red"> ${user.userName} </div>
<div style="color:red"> ${user.userPassword} </div>
</body>
4. 小结
本章节和大家一起讲解 Spring MVC 框架的重定向过程中是如何实现数据传递的,传递方式归纳起来就 2 种:
- 通过 URL 附加数据的方式传递数据;
- 使用 Spring MVC 提供的 RedirectAttributes 组件实现数据的传递。
两种方式各有属于自己的应用场景,数据量不多时可以使用第一种方案。数据以对象方式进行传递时可使用第二种方案。