Chao's Blog Chao's Blog
首页
  • vue

    • vue路由
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • java
  • spring
  • springboot
  • springcloud
  • git
  • maven
  • nginx
  • tomcat
  • springmvc
  • jvm
  • 图数据库
  • mysql数据库
  • redis数据库
  • windows下docker安装nginx并挂载目录
  • linux命令
  • linux安装软件
  • linux脚本
  • idea
  • vscode
  • 归档
  • 综合项目

    • 若依项目
    • mall项目
  • java
  • mybatis
  • xxl-job
  • mybatis
GitHub (opens new window)

~chao

永远菜鸟,不断努力~
首页
  • vue

    • vue路由
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • java
  • spring
  • springboot
  • springcloud
  • git
  • maven
  • nginx
  • tomcat
  • springmvc
  • jvm
  • 图数据库
  • mysql数据库
  • redis数据库
  • windows下docker安装nginx并挂载目录
  • linux命令
  • linux安装软件
  • linux脚本
  • idea
  • vscode
  • 归档
  • 综合项目

    • 若依项目
    • mall项目
  • java
  • mybatis
  • xxl-job
  • mybatis
GitHub (opens new window)
  • java

  • spring

  • springboot

  • springcloud

  • git

  • maven

  • nginx

  • tomcat

  • springmvc

    • 基础

      • SpringMVC简介
      • RequestMapping 注解
      • SpringMVC获取请求参数
      • 域对象共享数据
        • 1、三种域对象
        • 2、向 request 域对象共享数据
          • 2.1、通过 Servlet API
          • 2.2、通过 ModelAndView
          • 2.3、通过 Model
          • 2.4、通过 Map
          • 2.5、通过 ModelMap
          • 2.6、Model、ModelMap 和 Map
        • 3、向 session 域共享数据
        • 4、向 application 域共享数据
        • 总结
      • SpringMVC视图
      • RESTful
      • RESTful案例
      • HttpMessageConverter
      • 拦截器和异常处理
      • 完全注解开发
      • SpringMVC 执行流程
    • 总结

  • jvm

  • 正则表达式

  • 消息中间件

  • python

  • 后端
  • springmvc
  • 基础
~chao
2022-12-16
目录

域对象共享数据

笔记来源:【尚硅谷】SpringMVC教程丨一套快速上手spring mvc (opens new window)

[TOC]

# 域对象共享数据

# 1、三种域对象

  • Request:一次请求
  • Session:一次会话。从浏览器开启到浏览器关闭(只跟浏览器是否关闭有关,与服务器是否关闭无关)
    • 钝化:浏览器未关闭而服务器关闭,Session数据序列化到磁盘上
    • 活化:浏览器仍然关闭而服务器开启,将钝化内容读取到Session中
  • Application/Servlet Context:上下文对象,整个应用范围。服务器开启时创建,服务器关闭时销毁,从头到尾只创建一次(只跟服务器是否关闭有关,与浏览器是否关闭无关)

选择域对象时,应该选择能实现功能、范围最小的域对象

# 2、向 request 域对象共享数据

# 2.1、通过 Servlet API

后台测试代码

@RequestMapping("/testRequestByServletAPI")
public String testRequestByServletAPI(HttpServletRequest request) {
    request.setAttribute("testRequestScope", "hello, Servlet API!");
    return "successrequest";
}
1
2
3
4
5

前台测试代码

index.html

<a th:href="@{/scopeController/testRequestByServletAPI}">通过Servlet API</a>
1

successrequest.html

<p th:text="${testRequestScope}"></p>
1

测试结果

动画  (4)

可以发现,转发的页面中成功获取到了在后台通过Request对象向request域中设置的属性值并正确展示

# 2.2、通过 ModelAndView

食用方式:在 SpringMVC 中,不管用的何种方式,本质上最后都会封装到ModelAndView。同时要注意使用ModelAndView向 request 域对象共享数据时,需要返回ModelAndView自身

后台测试代码

@RequestMapping("/testRequestByModelAndView")
public ModelAndView testRequestByModelAndView() {
    /**
     * ModelAndView有Model和View两个功能
     * Model用于向请求域共享数据
     * View用于设置视图,实现页面跳转
     */
    ModelAndView mv = new ModelAndView();
    //向请求域共享数据
    mv.addObject("testRequestScope", "hello, ModelAndView!");
    //设置视图,实现页面跳转
    mv.setViewName("successrequest");
    return mv;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

前台测试代码

<a th:href="@{/scopeController/testRequestByModelAndView}">通过 ModelAndView</a><br/>
1

测试结果

动画  (5)

# 2.3、通过 Model

食用方式:形式与HttpServletRequest类似

后台测试代码

@RequestMapping("/testRequestByModel")
public String testRequestByModel(Model model) {
    //向请求域共享数据
    model.addAttribute("testRequestScope", "hello, ModelAndView!");
    return "successrequest";
}
1
2
3
4
5
6

前台测试代码

<a th:href="@{/scopeController/testRequestByModel}">通过 Model</a><br/>
1

测试结果

动画  (6)

# 2.4、通过 Map

食用方式:形式与Model方式类似

后台测试代码

@RequestMapping("/testRequestByMap")
public String testRequestByMap(Map<String, Object> map) {
    //向请求域共享数据
    map.put("testRequestScope", "hello, Map!");
    return "successrequest";
}
1
2
3
4
5
6

前台测试代码

<a th:href="@{/scopeController/testRequestByMap}">通过 Map</a><br/>
1

测试结果

动画  (7)

# 2.5、通过 ModelMap

食用方式:形式与Model方式类似

后台测试代码

@RequestMapping("/testRequestByModelMap")
public String testRequestByModelMap(ModelMap modelMap) {
    //向请求域共享数据
    modelMap.addAttribute("testRequestScope", "hello, ModelMap!");
    return "successrequest";
}
1
2
3
4
5
6

前台测试代码

<a th:href="@{/scopeController/testRequestByModelMap}">通过 ModelMap</a><br/>
1

测试结果

动画  (8)

# 2.6、Model、ModelMap 和 Map

分别在上述对应的控制器方法中,添加打印 Model、ModelMap 和 Map 三个对象及其对应类名的逻辑

System.out.println(model + "======" + model.getClass().getName());
System.out.println(map + "======" + map.getClass().getName());
System.out.println(modelMap + "======" + modelMap.getClass().getName());
1
2
3

通过分别点击前台超链接,并查看后台日志信息

{testRequestScope=hello, Model!}======org.springframework.validation.support.BindingAwareModelMap
{testRequestScope=hello, Map!}======org.springframework.validation.support.BindingAwareModelMap
{testRequestScope=hello, ModelMap!}======org.springframework.validation.support.BindingAwareModelMap
1
2
3

可以发现

  • Model、ModelMap 和 Map 三个对象输入格式是一致的,都为键值对形式
  • 通过反射方法获取到的类都是同一个,即BindingAwareModelMap

查看BindingAwareModelMap的继承关系

image-20220321211709324

阅读源码,梳理出Model、Map、ModelMap三者的核心继承关系

public class BindingAwareModelMap extends ExtendedModelMap {}
public class ExtendedModelMap extends ModelMap implements Model {}
public class ModelMap extends LinkedHashMap<String, Object> {}
public interface Model {}
1
2
3
4

可以发现

  • BindingAwareModelMap继承ModelMap并实现Model接口
  • ModelMap继承LinkedHashMap,而毫无疑问LinkedHashMap实现了Map接口

Model、Map和ModelMap三者的关系到此就一目了然了,其 UML 类图如下:

ModelMap

结论:Model、Map、ModelMap类型的形参本质上都是BindingAwareModelMap

# 3、向 session 域共享数据

食用方式:形式与HttpServletRequest方式类似,形参为HttpSession。需要注意的是 SpringMVC 虽然提供了一个@SessionAttribute注解,但并不好用,因此反而建议直接使用原生 Servlet 中的HttpSession对象

后台测试代码

@RequestMapping("/testSession")
public String testSession(HttpSession session) {
    //向session域共享数据
    session.setAttribute("testSessionScope", "hello, HttpSession!");
    return "successsession";
}
1
2
3
4
5
6

前台测试代码

index.html

<a th:href="@{/scopeController/testSession}">通过 Servlet API 向 Session 域对象共享数据</a><br/>
1

successsession.html

<p th:text="${session.testSessionScope}"></p>
1

测试结果

动画  (9)

# 4、向 application 域共享数据

食用方式:形式与HttpSession方式类似,只不过需要先从session对象中获取ServletContext上下文对象,即application域对象,再做操作

后台测试代码

@RequestMapping("/testApplication")
public String testApplication(HttpSession session) {
    ServletContext application = session.getServletContext();
    application.setAttribute("testApplicationScope", "hello, application!");
    return "successapplication";
}
1
2
3
4
5
6

前台测试代码

index.html

<a th:href="@{/scopeController/testApplication}">通过 Servlet API 向 Application 域对象共享数据</a><br/>
1

successapplication.html

<p th:text="${application.testApplicationScope}"></p>
1

测试结果

动画  (10)

# 总结

域对象有三种:request(请求域)、session(会话域)和application(上下文)

向request域对象共享数据方式:本质都是ModelAndView

  • Servlet API(不推荐):HttpServletRequest
  • ModelAndView:需要返回自身
  • Model、Map、ModelMap:本质都是BindingAwareModelMap

向session域共享数据:HttpSession

向application域共享数据:ServletContext

附上导图,仅供参考

03-域对象共享数据

编辑 (opens new window)
上次更新: 2024/01/26, 05:03:22
SpringMVC获取请求参数
SpringMVC视图

← SpringMVC获取请求参数 SpringMVC视图→

最近更新
01
python使用生成器读取大文件-500g
09-24
02
Windows环境下 Docker Desktop 安装 Nginx
04-10
03
使用nginx部署多个前端项目(三种方式)
04-10
更多文章>
Theme by Vdoing | Copyright © 2022-2024 chaos | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式