1、SpringMVC中的域对象
此处只有request、session、servletContext被使用,而page是jsp页面的域,不使用jsp。
- request:一次请求的范围内
 - session:一次会话的范围内
 - servletContext:整个web的应用范围内
 
2、向request域对象共享数据的几种方式
(1)使用ServletAPI
控制器方法存入数据
@RequestMapping("/testRequestByServletAPI")
public String testRequestByServletAPI(HttpServletRequest request){
    request.setAttribute("username", "zhangsan");
    request.setAttribute("password", "123456");
    return "success";
} 
前端页面读取数据
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Success</title>
    </head>
    <body>
        <h3>success</h3><br>
        <p th:text="${username}"></p>
        <p th:text="${password}"></p>
    </body>
</html> 
(2)使用ModelAndView
什么是ModelAndView
ModelAndView是一个类,可以利用它的对象设置当前请求的
视图跳转与数据共享。不管使用什么方式,Spring最终都会将模型数据和视图封装到ModelAndView中。
ModelAndView对象的作用
有两个功能。
Model:向request域中共享数据
View:设置视图跳转。可以设置视图名称(setViewName),也可以设置视图(setView)
示例
通过ModelAndView,向request域中存放数据
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
    ModelAndView mav = new ModelAndView();
    //处理模型数据,即向request域共享数据
    mav.addObject("username", "lisi");
    mav.addObject("password", "456789");
    //处理视图数据,即设置视图名称
    mav.setViewName("success");
    return mav;
} 
读取数据和之前的前端页面一致
<p th:text="${username}"></p>
<p th:text="${password}"></p> 
注意
如果在控制器方法中使用了ModelAndView对象,那么
该mav对象必须作为方法的返回值返回。否则SpringMVC无法知晓你使用了ModelAndView
(3)使用Model
什么是Model
指的是ModelAndView中的Model
Model的作用
共享数据
示例
@RequestMapping("/testModel")
public String testModel(Model model){
    model.addAttribute("username", "wangwu");
    model.addAttribute("password", "555555");
    return "success";
} 
注意
单独使用Model
- 形参是Model类型
 - 返回值是String类型,返回视图名称
 
(4)使用Map集合
什么叫使用map向request域共享数据
之前将Model类型作为控制器方法的形参,通过设置model的参数,就达到了共享数据的效果。
如果使用Map集合,也是一样的效果。
将Map类型作为形参,方法体中给map添加键值对,也可以直接将键值对保存到域对象。
示例
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
    map.put("username", "gaoliu");
    map.put("password", "666666");
    return "success";
} 
(6)原理分析及总结
a. 为什么Model、ModelMap、Map,都能以同样的方式共享数据?
Model、ModelMap、Map类型的参数,其实本质上都是 BindingAwareModelMap 类型。这是Spring做的,并不是原生类型。
具体来说,它们实例化时,都用的是 BindingAwareModelMap 这个类。
那么Model、ModelMap、Map一定存在着联系。
先看Model的源码
public interface Model {...}说明它是Spring中,模型部分的顶层接口。
ModelMap的源码
public class ModelMap extends LinkedHashMap<String, Object> {...}它继承了LinkedHashMap,而LinkedHashMap实现了Map接口。所以
ModelMap也属于一个Map接口的实现类。ModelMap的继承结构

BindAwareModelMap是ModelMap的子类,所以BindAwareModelMap可以实例化ModelMap。既然ModelMap实现了Map,那么BindAwareModelMap也可以实例化Map。
BindAwareModelMap的继承结构
BindAwareModelMap的父类是ExtendedModelMap
public class ExtendedModelMap extends ModelMap implements Model {...} 
而ExtendedModelMap继承了ModelMap类,并且实现了Model接口,所以BindAwareModelMap可以实例化Model类型。
总结
Model、ModelMap、Map的关系:
public interface Model{}
public class ModelMap extends LinkedHashMap<String, Object> {}
public class ExtendedModelMap extends ModelMap implements Model {}
public class BindingAwareModelMap extends ExtendedModelMap {} 

b.为什么这几种方式都没有指定request域,却都被称作向request域对象中共享数据?
首先,Model、ModelMap或是Map的方式,最终都会由SpringMVC封装成ModelAndView对象。
而使用ModelAndView的方式,是我们自己组装了ModelAndView对象并返回给了SpringMVC。
所以,这个问题的本质是,ModelAndView对象如何向request域对象中存放数据?
ModelandView是将 视图信息和数据封装到一起的,spring来解析ModelandView中的信息,包括视图和数据 ,然后将数据set到request里面,并且根据model里面的视图信息以及spring mvc的配置让request进行跳转。
3、向session域对象共享数据
使用ServletAPI比较简单
@RequestMapping("/testSession")
public String testSession(HttpSession session){
    session.setAttribute("username", "xiaowb");
    session.setAttribute("password", "000000");
    return "success";
} 
前端获取session域对象中的值
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Success</title>
    </head>
    <body>
        <h3>success</h3><br>
        <p th:text="${session.username}"></p>
        <p th:text="${session.password}"></p>
    </body>
</html> 
thymeleaf获取session域对象中的数据时,需要加
session.键名
4、向servletContext域对象共享数据
注意
在jsp、Thymeleaf等
模板引擎中,servletContext通常被叫做application,本质是一样的。所以在获取servletContext对象时,最好也叫做application。
使用ServletAPI比较简单
@RequestMapping("/testSessionContext")
public String testServletContext(HttpSession session){
    ServletContext application = session.getServletContext();
    application.setAttribute("username", "xiaocs");
    application.setAttribute("password", "999999");
    return "success";
} 
前端获取application域对象中的值
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Success</title>
    </head>
    <body>
        <h3>success</h3><br>
        <p th:text="${application.username}"></p>
        <p th:text="${application.password}"></p>
    </body>
</html> 
thymeleaf获取application域对象中的数据时,需要加application.键名




![[渗透教程]-015-网络与系统渗透](https://img-blog.csdnimg.cn/img_convert/00cbe7c00049a61b1153b73b325a57b4.png)














