域对象共享数据
一、域对象共享的方式及范围选择
-
request
作用范围:一次请求
-
session
作用范围:一次会话,即浏览器的开启 - 关闭
浏览器的钝化和活化,钝化是指浏览器未关闭,服务器关闭了,此时session中的数据就会序列化后存储到硬盘上;活化是指浏览器仍未关闭,服务器又开启了,那么序列化到硬盘中的数据又会重新读取到浏览器的session中
-
application(ServletContext)
作用范围:整个应用,即服务器的开启 - 关闭
-
范围选择
原则:能实现功能的,范围最小的域对象
比如:实现查询数据,每一次查询数据都要重新查取最新数据,因为数据在此之前可能发生了增删改操作,所以这个域对象放在request中即可,就在当前请求中使用一次,如果放在session中,就会造成资源浪费
-
回顾:使用ServletAPI共享域对象
对域对象的操作有三种:setAttribute、getAttribute、removeAttribute
controller
@Controller public class ScopeController { // request请求的作用域共享对象 @RequestMapping("/testRequest") public String servletApiTest(HttpServletRequest request) { request.setAttribute("testRequestScope","hello,Request"); // 转发至success.html,故在success.html页面内即可获取到该域对象 return "success"; } // session请求的作用域共享对象 @RequestMapping("/testSession") public String servletApiTest(HttpServletRequest request) { session.setAttribute("testRequestScope","hello,Session"); return "success"; } // application请求的作用域共享对象 @RequestMapping("/testApplication") public String servletApiTest(HttpServletRequest request) { ServletContext application = session.getServletContext(); session.setAttribute("testRequestScope","hello,Application"); return "success"; } }
html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2>success</h2> 获取request共享域对象:<p th:text="${testRequestScope}"></p> 获取session共享域对象:<p th:text="${session.testRequestScope}"></p> 获取application共享域对象:<p th:text="${application.testRequestScope}"></p> </body> </html>
二、ModelAndView 向request域对象中共享数据(推荐使用)
-
ModelAndView有两个功能
Model:主要用于向请求域中共享数据(也叫处理模型数据)
View:用于设置视图,实现页面跳转
-
核心功能
域对象共享数据的所有方式,最终都会将Model模型数据和View视图封装到ModelAndView对象内
-
控制方法的返回值类型必须是ModelAndView
html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h1>首页</h1> <a th:href="@{/testModelAndView}">测试ModelAndView</a> </body> </html>
controller
@Controller public class ScopeController { @RequestMapping("/testModelAndView") public ModelAndView modelAndViewTest() { ModelAndView mav = new ModelAndView(); /* 处理模型数据,即request域对象中共享数据,下面是addObject方法的源码: public ModelAndView addObject(String attributeName, @Nullable Object attributeValue) { this.getModelMap().addAttribute(attributeName, attributeValue); return this; } */ mav.addObject("testRequestScope", "Hello,ModelAndView"); // 设置视图名称:setViewName mav.setViewName("success"); return mav; } }
三、Model向rRequest域对象中共享数据
-
Model就是ModelAndView中的Model
-
代码测试
controller
@Controller public class ScopeController { @RequestMapping("/testModel") // org.springframework.ui.Model public String modelTest(Model model) { model.addAttribute("testRequestScope","Hello,Model"); // 打印结果为:{testRequestScope=Hello,Model} System.out.println(model); // org.springframework.validation.support.BindingAwareModelMap System.out.println(model.getClass().getName()); return "success"; } }
四、Map向request域对象中共享数据
-
在Map的键值对内,键:域对象,值:域对象的值
-
代码测试
controller
@Controller public class ScopeController { @RequestMapping("/testMap") public String modelTest(Map<String,Object> map) { map.put("testRequestScope","Hello,Map"); // 打印结果为:{testRequestScope=Hello,Model} System.out.println(map); // org.springframework.validation.support.BindingAwareModelMap System.out.println(map.getClass().getName()); return "success"; } }
五、ModelMap向rRequest域对象中共享数据
-
和Model的使用一样
-
代码测试
controller
@Controller public class ScopeController { @RequestMapping("/testModelMap") public String modelMapTest(ModelMap modelMap) { modelMap.addAttribute("testRequestScope","Hello,ModelMap"); // 打印结果为:{testRequestScope=Hello,Model} System.out.println(modelMap); // org.springframework.validation.support.BindingAwareModelMap System.out.println(modelMap.getClass().getName()); return "success"; } }
六、Model、Map、ModelMap之间的关系
-
从测试结果得知:三者的实例化对象的类都是BindingAwareModelMap
-
源码直接的继承实现关系
public class BindingAwareModelMap extends ExtendedModelMap { public class ExtendedModelMap extends ModelMap implements Model { public class ModelMap extends LinkedHashMap<String, Object> { public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {