Spring MVC学习 | 使用域对象共享数据

news2024/11/30 14:52:03

文章目录

  • 一、回顾域对象
  • 二、在request域共享数据
    • 2.1 使用ServletAPI
    • 2.2 使用ModelAndView对象
    • 2.3 使用Model对象
    • 2.4 使用ModelMap对象
    • 2.5 使用Map集合
    • 2.6 Model、ModelMap和Map的关系
    • 2.7 使用域对象的底层原理
  • 三、在session域共享数据
  • 四、在application域共享数据


学习视频🎥:https://www.bilibili.com/video/BV1Ry4y1574R

一、回顾域对象

🔑Java Web中的四种域对象及其作用域(范围)

  • pageContext ->当前页面,范围最小。pageContext一般用于jsp页面,作用域仅为当前jsp页面,而Spring MVC不使用jsp,都是用html页面,所以下面仅介绍后面三种

  • request ->一次请求

  • session ->一次会话

  • application ->整个web工程,范围最大

🔑域对象的使用规则:在能实现功能的前提下,选用范围更小的域对象


二、在request域共享数据

2.1 使用ServletAPI

💬概述:直接使用原生的servlet API向request域中共享数据,即使用req.setAttribute("数据名", "数据值")

🔑使用

① 在控制器方法形参上添加HttpServletRequest类型的对象req,此时req对象就表示当前请求,然后直接根据req对象调用setAttribute()方法,实现在request域中存储数据(与获取请求参数的使用类似)

@RequestMapping("/testScope01")
public String showTestScope01(HttpServletRequest req) {
    // 直接调用方法向request域中存储数据
    req.setAttribute("testData", "hello,servlet API!");
    
    return "testScope";
}

② 在测试域对象页面testScope.html中获取requet域中的数据,request域中的数据可以直接通过数据名获取(下面四种方式都是采用该页面进行测试)

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

💡 html页面中不能使用EL表达式,所以需要使用thymeleaf语法(th:text)来获取域对象数据,注意${"数据名"}是写在th:text中,不是写在<p>的标签体内

2.2 使用ModelAndView对象

💬概述modelAndView对象是Spring MVC用来处理模型数据(model)和视图数据(view)的重要对象,Spring MVC使用域对象共享数据的5种方法底层都是通过modelAndView对象实现(后续分析源码可知)

🔑分析modelAndView对象

  • modelAndView可分为两个部分——model和view,两个部分负责不同功能
    ① model:表示模型数据,主要用于向request域中共享数据,相当于一个Model类型的对象
    ② view:表示视图数据,主要用于设置视图,实现页面的跳转
  • modelAndView对象的两个主要方法
    addObject("数据名", 数据值):通过数据名(String)和数据值(Object)往request域中存储数据,与原生servlet API的req.setAttribute()方法类似
    setViewName("视图名"):设置视图名称,该方法的功能与原先控制器中返回一个视图名的功能一样(return "视图名"),都是设置一个视图名称交给视图解析器(thymeleaf)解析,获取到完整页面路径后实现页面跳转

🔑使用:创建控制器方法,方法返回类型为ModelAndView,无需添加形参,在方法内先创建一个ModelAndView类型的对象mav,然后通过mav对象分别调用addObject()setViewName()两个方法,实现向域中存储数据和设置视图名,最后将mav对象返回

❓ 为什么要把控制器方法返回值类型为ModelAndView:Spring MVC(或者说前端控制器DispatcherServlet)需要获取modelAndView对象,才能知道我们在域中存储的数据以及要转发的页面,而modelAndView对象是在方法内创建的,不是作为方法形参,所以就必须要把我们创建的modelAndView对象返回,Spring MVC才能获取到

@RequestMapping("/testScope02")
public ModelAndView showTestScope02() {
    ModelAndView mav = new ModelAndView();
    
    // 往request域中存储数据
    mav.addObject("testData", "hello,ModelAndView!");
    
    // 设置视图名
    mav.setViewName("testScope");
    
    // 最后返回mav对象
    return mav;
}

2.3 使用Model对象

🔑分析model对象

  • model对象相当于ModelAndView对象中的model部分,主要用于向request域中存储数据
  • model对象的方法——addAttribute("数据名", 数据值):通过数据名和数据值向request域中存储数据,与mav.addObject()req.setAttribute()用法一样

🔑使用:创建控制器方法,方法返回值类型为String,并添加一个Model类型的形参model,然后在方法中直接使用model对象调用addAttribute()方法,往request域中存储数据,最后再返回视图名

@RequestMapping("/testScope03")
public String showTestScope03(Model model) {
    // 往request域中存储数据
    model.addAttribute("testData", "hello,Model!");
    
    return "testScope";
}

2.4 使用ModelMap对象

💬概述ModelMap对象和Model对象类似,modelMap对象同样通过是调用addAttribute()方法实现往request域中存储数据

🔑使用

@RequestMapping("/testScope04")
public String showTestScope04(ModelMap modelMap) {
    // 往request域中存储数据
    modelMap.addAttribute("testData", "hello,ModelMap!");
    
    return "testScope";
}

2.5 使用Map集合

💬概述:Spring MVC中可以使用Map集合向request域中存储数据,Map集合中的键值对(key-value)分别对应request域中的数据名(key)和数据值(value)

🔑使用:创建控制器方法,方法中添加Map<String, Object>集合类型的形参scopeMap,然后在方法中直接使用map集合的put()方法,将数据名和数据值建立键值对关系,从而实现request域中存储数据

@RequestMapping("/testScope05")
public String showTestScope05(Map<String, Object> scopeMap) {
    // 直接在map集合中存储数据
    scopeMap.put("testData", "hello,Map!");
    
    return "testScope";
}

2.6 Model、ModelMap和Map的关系

  • 在上述测试控制器方法中分别打印出modelmodelMapscopeMap三个对象,观察控制台打印结果。打印结果显示,三个对象的打印结果类似,都是{数据名=数据值}的形式
    model-print01

    💡 一般直接打印对象,结果会显示对象的内存地址,说明实例化这三个对象的类中的toString()方法被重写过,且重写后的打印形式类型,说明实例化三个对象的类有可能是同一个

  • 通过反射的方式——对象.getClass().getName()获取实例化三个对象的类的全类名并打印到控制台,打印结果发现,实例化三个对象的类是同一个,都是BindingAwareModelMap
    model-print02

  • 分析四个类各自的源码

    ① Map:JDK中的底层接口
    map

    ② Model:Spring MVC底层的接口(与其他类或接口无继承关系)
    model

    ③ ModelMap:继承LinkHashMap<String, Object>类,而LinkHashMap<String, Object>实现Map接口
    modelMap ④ BindingAwareModelMap:继承ExtendedModelMap类,而ExtendedModelMap类又继承ModelMap,并实现Model接口
    binding
    extendsModelMap
    extends

  • 四个类的关系图(类图):由类图中可以看出BindingAwareModelMap类与ModelModelMapMap三个类或接口之间的关系,以及ModelModelMapMap都能被BindingAwareModelMap实例化
    extends02.

2.7 使用域对象的底层原理

🔑底层原理:在控制器方法执行后,前端控制器DispatcherServlet会将控制器方法中的模型数据和视图数据封装成一个ModelAndView对象,然后根据该对象向request域中共享数据,并将视图数据(视图名)交给视图解析器解析,最后实现页面跳转

🔑分析源码

  • 在控制器方法中打上断点,debug模式启动,在页面点击链接跳转到断点处,此时在方法栈中可以看到所有间接或直接调用控制器方法的底层方法,我们关心前端控制器DispatcherServlet中的方法——doDispatch()
    doDispatch()

  • doDispatch()方法中,可以看到ha.handle()方法返回了一个mv对象,该对象就是一个ModelAndView对象,而ha.handle()方法的执行还会间接或直接调用控制器方法,由此可得,前端控制器DispatcherServlet在调用控制器方法之后,将控制器方法中的模型数据和视图数据封装成一个ModelAndView对象并获取,然后再根据该对象来进行后续操作
    mv

  • 在前端控制器获取mv对象中打上断点,进一步查看该对象的详细信息。mv对象信息中,正好有控制器方法中设置的模型数据(往request域中存储数据)和视图数据(视图名),这里的控制器方法为showTestScope03(),即使用model对应的控制器方法
    mv-data


三、在session域共享数据

💬概述:Spring MVC中可以通过原生的Servlet API获取session对象,然后再根据session对象调用setAttribute("数据名", 数据值)方法往session域中存储数据

🔑使用

① 创建控制器方法,方法上添加HttpSession类型的形参session,然后根据session对象调用方法,往session域中存储数据(与request域中共享数据类似)

@RequestMapping("/testSession")
public String showTestSession(HttpSession session) {
    // 直接使用session对象调用方法,往session域中存储数据
    session.setAttribute("testSessionData", "hello,session!");

    return "testScope";
}

② 在testScope.html页面中通过thymeleaf语法获取session域中的数据,注意要使用thymeleaf内置对象(session)来获取域中的数据,不能直接写数据名(request域中数据获取才可以直接写数据名)

<!-- 获取session域中数据 -->
<p th:text="${session.testSessionData}"></p>

四、在application域共享数据

💬概述:Spring MVC中同样可以通过原生的Servlet API获取servletContext对象,然后再根据servletContext对象调用setAttribute("数据名", 数据值)方法往application域中存储数据

🔧使用

① 创建控制器方法,方法上添加HttpSession类型的形参session先根据session对象获取servletContext对象(或者说application对象),然后根据servletContext对象调用方法,往application域中存储数据

@RequestMapping("/testApplication")
public String showTestApplication(HttpSession session) {
    // 直接使用session对象获取servletContext对象
    ServletContext servletContext = session.getServletContext();

    // 根据servletContext对象往application域中存储数据
    servletContext.setAttribute("testApplicationData", "hello,application!");

    return "testScope";
}

② 在testScope.html页面中通过thymeleaf语法获取application域中的数据,注意要使用thymeleaf内置对象(application)来获取域中的数据,不能直接写数据名

<!-- 获取application域中数据 -->
<p th:text="${application.testApplicationData}"></p>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/87496.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot 替换 if 的参数校验

简单使用 Java API规范(JSR303)定义了Bean校验的标准validation-api&#xff0c;但没有提供实现。hibernate validation是对这个规范的实现&#xff0c;并增加了校验注解如Email、Length等。 Spring Validation是对hibernate validation的二次封装&#xff0c;用于支持spring…

Windows 禁用驱动签名方式

Windows 禁用驱动签名方式1. Windows开启测试模式2. 强制禁用2.1 Win7、Win82.2 Win103. 开机选用强制开启禁用签名模式3.1 Win72.3 Win8、Win10及Win113. 参考1. Windows开启测试模式 以管理员模式启动cmd&#xff0c;输入以下命令&#xff1a; 开启系统的测试模式 bcdedit …

来自飞桨社区开发者的礼物,《动手学深度学习》飞桨版上线!

近几年&#xff0c;各行各业已经逐渐开始基于AI技术启动企业智能化转型&#xff0c;AI技术的广泛应用催生了对AI应用人才的需求。如何不断夯实自身的AI技术能力&#xff0c;提升自己的职业竞争力&#xff1f;飞桨社区的开发者给大家带来一份神秘礼物。李沐老师的《动手学深度学…

web前端网页设计期末课程大作业:旅游网页主题网站设计——紫色的旅游开发景点网站静态模板(4页)HTML+CSS+JavaScript

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

股票l2接口的委托数据有什么作用?

股票l2接口的委托数据有什么作用&#xff1f; 委托队列返回数据&#xff1a;Level 2 行情将真实的每笔成交和成交量以明细数据呈现给用户。 用户可通过查看明细成交数据&#xff0c;判断出委托是属于大单、中单、小单并以此推断出是机构、大户、散户等所为&#xff0c;查明主…

国内外远程办公软件现状

我们说的远程办公通常指狭义上的远程办公&#xff0c;是指通过远程技术&#xff0c;或远程控制软件&#xff0c;对远程电脑进行操作办公&#xff0c;实现非本地办公&#xff0c;如在家办公、异地办公、移动办公等远程办公模式。这种技术的关键在于:穿透内网和远程控制的安全性。…

软件工程期末复习

文章目录一、单选、多选、判断二、简答题1、MVC体系结构2、软件风险的分类3、测试准则&#xff08;教材P111- 5.2.3&#xff09;4、结构化分析的方法5、面向对象设计的原则&#xff08;SOLID&#xff09;&#xff08;1&#xff09;单一职责原则&#xff08;2&#xff09;开放/闭…

arduino-ide ESP32 开发

本来想用vscodePlatformIO 一直安装不成功&#xff0c;网不行。先用Arduino&#xff08;后来用手机开热点&#xff0c;安装成功了&#xff0c;电信的局域网真差&#xff09; 我的ESP开发版是CP2102驱动芯片&#xff0c;需要先安装驱动 CP210x USB to UART Bridge VCP Driver…

剑指 Offer 62. 圆圈中最后剩下的数字

文章目录题目思考代码和注释总结题目 0,1,,n-1这n个数字排成一个圆圈&#xff0c;从数字0开始&#xff0c;每次从这个圆圈里删除第m个数字&#xff08;删除后从下一个数字开始计数&#xff09;。求出这个圆圈里剩下的最后一个数字。 例如&#xff0c;0、1、2、3、4这5个数字组…

技术创新,她不断进取!冲在前端,开发是她!

单从数字比例上来看&#xff0c;前端开发工程师的女性占比相对整个行业来说较高。成为优秀的前端开发工程师&#xff0c;不论男女&#xff0c;你都可以&#xff01;本期工作坊就想跟你聊聊&#xff0c;想要成为一名优秀的前端开发应该具备怎样的能力&#xff1f;女性的哪些独特…

还在用HttpUtil?SpringBoot 3.0全新HTTP客户端工具来了,用起来够优雅!

我们平时开发项目的时候&#xff0c;经常会需要远程调用下其他服务提供的接口&#xff0c;于是我们会使用一些HTTP工具类比如Hutool提供的HttpUtil。前不久SpringBoot 3.0发布了&#xff0c;出了一个Http Interface的新特性&#xff0c;它允许我们使用声明式服务调用的方式来调…

Grafana 集成 Prometheum

参考文章&#xff1a; linux 上搭建grafana_摸鱼第一人的博客-CSDN博客_linux安装grafana 目录 一、安装 Grafana 二、安装 Prometheus 三、Prometheus 集成 Grafana 一、安装 Grafana 1、从官网下载rpm包 Download Grafana | Grafana Labs 2、将下载好的包上传到linu…

开源博客项目Blog .NET Core源码学习(2:数据库结构分析)

项目采用17张表以支撑博客内容展示及后台管理功能&#xff0c;本文结合数据库表中的存储数据&#xff0c;学习每张表的用途及其中字段的意义&#xff08;有部分字段暂时还不明白&#xff0c;后续学习代码时再逐步完善&#xff09;。 序号表名用途1CategoryInfo保存文章栏目的定…

vulntarget靶场系列-a-writeup

网络配置外网WIN7&#xff1a;ip1: 192.168.127.91/255.255.255.0 ,gw:192.168.127.2 (NAT模式)ip2:10.0.20.98-vmnet1(仅主机模式)域主机成员&#xff1a;10.0.20.99-vmnet1(仅主机模式)10.0.10.111-vmnet2(仅主机模式)域控&#xff1a;10.0.10.110-vmnet2(仅主机模式)密码配置…

C++11标准模板(STL)- 算法(std::max_element)

定义于头文件 <algorithm> 算法库提供大量用途的函数&#xff08;例如查找、排序、计数、操作&#xff09;&#xff0c;它们在元素范围上操作。注意范围定义为 [first, last) &#xff0c;其中 last 指代要查询或修改的最后元素的后一个元素。 返回范围内的最大元素 st…

2022 12月15日 每日面试题(MyBatis)

&#x1f3e0;个人主页&#xff1a;不会写代码的满满 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是满满&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; 目前状况&#x1f389;&#xff1a;开学即将大三&#xff0c;目标就是半年内找到一份实…

【云计算与大数据技术】资源管理、调度模型策略的讲解

一、资源管理模型 集群资源管理模型通常由两个部分组成&#xff0c;即资源表示模型和资源分配模型&#xff0c;由于这两个部分是耦合的&#xff0c;所有优化集群资源管理时需要同时结合这两个部分考虑&#xff0c;资源表示模型用于描述集群资源的组织方式&#xff0c;是集群资…

【Contrastive Learning:IVIF】

CLF-Net: Contrastive Learning for Infrared and Visible Image Fusion Network &#xff08;LF-Net&#xff1a;红外与可见光图像融合网络的对比学习&#xff09; &#xff08;总结&#xff1a;就是更像谁就选谁&#xff09; 本文提出了一种基于对比学习的红外和可见光图像融…

透过ChatGPT的进化足迹,OpenAI传达了哪些信号?

古希腊神话中&#xff0c;一位名叫赫尔墨斯的神&#xff0c;会充当人神之间的信使&#xff0c;穿着带有双翼的飞鞋&#xff0c;行走在神明与人类之间。根据《荷马史诗》的记载&#xff1a;“在天神中&#xff0c;赫尔墨斯是最喜欢引导凡人前行的。”这句话用来形容OpenAI与AI的…

佳力奇IPO过会:拟募资11亿 西安现代与华控湖北是股东

雷递网 雷建平 12月13日安徽佳力奇先进复合材料科技股份公司&#xff08;简称&#xff1a;“佳力奇”&#xff09;日前IPO过会&#xff0c;准备在深交所创业板上市。佳力奇计划募资11.22亿元&#xff0c;其中&#xff0c;6.2亿元用于先进复合材料数智化生产基地建设项目&#x…