当前位置: 首页 > news >正文

SpringMVC Day 05 : Spring 中的 Model

前言

欢迎来到 SpringMVC 系列教程的第五天!在之前的教程中,我们已经学习了如何使用控制器处理请求和返回视图。今天,我们将深入探讨 Spring 中的 Model。

在 Web 应用程序开发中,数据的传递和展示是非常重要的。SpringMVC 提供了一个名为 Model 的机制,用于在控制器和视图之间传递数据。Model 在 SpringMVC 中充当着数据容器的角色,它可以存储和传递各种类型的数据,例如对象、集合、基本类型等。

在本教程中,我们将详细介绍 Spring 中的 Model,并学习如何在控制器中使用它来传递数据给视图。我们还将探讨如何在视图中获取和展示 Model 中的数据。

现在,让我们开始学习 Spring 中的 Model,了解它的作用和用法,以及如何在应用程序中充分利用它来传递和展示数据。

一、前期准备

1、新建项目,结构如下

2、导入依赖
    <dependencies><!-- springmvc 依赖,会将spring的核心包一并添加进来 --><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.23</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.4.5</version></dependency></dependencies>
 3、配置 web.xml 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>

用于配置 Servlet 的映射和加载。在 Spring MVC 中,它用于配置 DispatcherServlet 的初始化和请求映射。

具体来说,这段配置的作用如下:

  1. 定义了一个名为 "dispatcher" 的 Servlet,并指定了 org.springframework.web.servlet.DispatcherServlet 作为其处理类。
  2. 设置了 load-on-startup 属性为 1,表示在应用启动时就加载该 Servlet。
  3. 使用 <servlet-mapping> 元素将 "dispatcher" Servlet 映射到所有的请求路径上(即 <url-pattern>/</url-pattern>),意味着所有的请求都会经过该 Servlet 进行处理。

 这段配置的作用是将所有的请求交给 DispatcherServlet 处理,并让它成为应用的核心控制器。DispatcherServlet 将根据请求的 URL 和其他配置信息,将请求分发给相应的处理器方法进行处理,然后返回响应结果。

4、配置 dispatcher-servlet.xml 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:mcv="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 启用扫描 --><context:component-scan base-package="edu.nf.ch05"/><!-- mvc 注解驱动 --><mvc:annotation-driven/><!-- 默认 servlet 处理静态资源 --><mcv:default-servlet-handler/><!-- 内部资源视图解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean></beans>

 主要作用是配置Spring MVC框架相关的组件和参数,以便在Web应用中使用Spring MVC框架进行开发。

具体来说,该配置文件包含以下几个部分:

  1. 命名空间声明:声明了XML文件所使用的命名空间,包括beans、context和mvc三个命名空间。

  2. 组件扫描:通过context:component-scan标签启用组件扫描机制,指定需要扫描的包路径,以便Spring MVC框架能够自动扫描和注册相关的组件。

  3. 注解驱动:通过mvc:annotation-driven标签启用注解驱动机制,使得Spring MVC框架能够自动识别和处理控制器中的注解,例如@RequestMapping、@ResponseBody等。

  4. 静态资源处理:通过mcv:default-servlet-handler标签配置默认的servlet处理静态资源,以便在Web应用中访问静态资源,例如图片、CSS、JavaScript等。

  5. 视图解析器:通过<bean>标签配置视图解析器,将JSP页面映射到对应的控制器方法上,以便返回相应的视图。

二、将 map 设置到 ModelAndView 中

@Controller
public class ModelController {@GetMapping("/test1")public ModelAndView test1() {ModelAndView mav = new ModelAndView("index");// 设置请求作用域mav.addObject("name", "qiu");// 也可以将数据保存到 map 集合中,再设置列到 ModelAndViewMap<String, Object> map = new HashMap<>();map.put("age", 21);// 再将 map 设置到 ModelAndView 中mav.addAllObjects(map);return mav;}
}

这段代码的意思是:

  1. 使用了 @GetMapping("/test1") 注解来处理 GET 请求,并将请求映射到路径 "/test1"。

  2. 该方法返回一个 ModelAndView 对象,并设置视图名称为 "index"。

  3. 使用 mav.addObject() 方法将参数保存到请求作用域中,参数名作为键,参数值作为值。在这个例子中,将 "name" 设置为 "qiu"。

  4. 还可以将数据保存到一个 Map 集合中,并使用 mav.addAllObjects() 方法将整个 Map 设置到 ModelAndView 中。在这个例子中,将 "age" 设置为 21。

  5. 最后,将数据保存到请求作用域中,并将视图名称设置为 "index",然后返回 ModelAndView 对象。

 1、在 index.jsp 中获取控制器保存的数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<h1>首页</h1>
Name:${requestScope.name}<br>
Age:${requestScope.age}
</body>
</html>
2、运行

这个方法的作用是将数据传递给视图,以便在视图中进行展示。具体来说,它通过 ModelAndView 对象将数据保存到请求作用域中,并将视图名称设置为 "index",然后返回该对象。

在 SpringMVC 中,控制器负责处理请求并返回视图。当控制器需要将数据传递给视图时,可以使用 ModelAndView 对象。ModelAndView 对象允许控制器设置视图名称、模型数据和其他参数,并将它们传递给视图进行展示。

在这个例子中,控制器通过 mav.addObject() 方法和 mav.addAllObjects() 方法将数据保存到请求作用域中。这些数据可以是任何类型的对象,例如字符串、数字、集合、自定义对象等。在视图中,可以通过 ${name}${age} 等表达式获取对应的参数值进行展示。

三、传入一个 Map,保存到 ModelAndView 中

1、Map 
 /*** Spring 可以传入一个 Map 、Model 或者 ModelMap* 来保存用户需要转发的数据,这些数据一样会保存到请求* 作用域中* @param map* @return*/@GetMapping("/test2")public ModelAndView test2(Map<String, Object> map) {map.put("name", "qiu");map.put("age", 21);return new ModelAndView("index");}

控制器的方法接受一个 Map<String, Object> 参数,该参数会自动被 SpringMVC 注入。

在方法体内,你可以通过 map.put() 方法将需要传递给视图的数据保存到这个 Map 对象中。在这个例子中,将 "name" 设置为 "qiu",将 "age" 设置为 21。

最后,通过创建一个新的 ModelAndView 对象并设置视图名称为 "index",将数据传递给视图。由于 Map 参数已经保存了需要传递的数据,因此不需要再调用 mav.addObject()mav.addAllObjects() 方法。

这种方式与之前的方式相比,省去了创建 ModelAndView 对象的步骤,直接通过方法参数进行数据传递。这样可以简化代码,并且在方法体内可以更直接地操作数据。

 2、Model
@GetMapping("/test3")
public String test3(Model model) {model.addAttribute("name", "qiu");model.addAttribute("age", 21);return "index";
}

控制器的方法接受一个 Model 参数,该参数会自动被 SpringMVC 注入。与之前的 Map 参数类似,你可以通过 model.addAttribute() 方法将需要传递给视图的数据保存到 Model 对象中。

最后,直接返回视图名称即可。由于 Model 参数已经保存了需要传递的数据,因此不需要再创建 ModelAndView 对象。

3、ModelMap
@GetMapping("/test4")
public String test4(ModelMap modelMap) {modelMap.put("name", "qiu");modelMap.put("age", 21);return "index";
}

方法参数是 ModelMap 对象,代码与 Map 参数的情况类似,只需要将方法参数类型改为 ModelMap 即可。

4、运行效果
 

最后它们运行的结果都是一样的,都是能把数据显示到页面中。 

四、原生 servlet 的传递参数和使用 Spring 中的 Model 传递参数有什么区别

原生 Servlet 的传递参数通常通过 HttpServletRequest 对象来实现,可以使用请求参数、请求头、请求体等方式传递数据。而在 Spring 中,Model 是一种更高级的数据传递方式,用于将数据从控制器传递到视图。

以下是原生 Servlet 和使用 Spring 中的 Model 传递参数的区别:

  1. 数据封装方式:原生 Servlet 需要手动从 HttpServletRequest 中获取参数,并进行解析和封装;而使用 Spring 的 Model 则是通过调用 addAttribute() 方法将数据添加到 Model 中,Spring 框架会自动将数据传递给视图。

  2. 数据范围:原生 Servlet 的参数传递范围局限于单个请求,参数只能在当前请求中传递;而使用 Spring 的 Model,数据可以在整个请求处理过程中共享,包括请求转发、重定向等情况下都可以传递数据。

  3. 视图解析:原生 Servlet 需要手动编写代码来进行视图解析,如使用 RequestDispatcher 进行请求转发或设置响应结果;而使用 Spring 的 Model,则由 Spring MVC 框架负责解析视图,根据配置的视图解析器将模型数据渲染到相应的视图上。

  4. 框架集成:原生 Servlet 是 Java EE 标准的一部分,可以与其他 Java EE 技术无缝集成;而使用 Spring 的 Model,需要结合 Spring MVC 框架进行使用,可以充分利用 Spring 提供的各种便利功能,如拦截器、AOP 等。

总的来说,使用 Spring 的 Model 传递参数相对于原生 Servlet 更加简洁、方便,并且能够与 Spring MVC 框架的其他功能无缝集成。它提供了一种高级的数据传递方式,使得开发人员能够更加专注于业务逻辑的实现,而不需要过多关注底层的参数解析和视图解析等细节。

 

五、使用 Spring 中的 Model 有什么好处

在 Spring 中,Model 是一个接口,它允许控制器方法向视图传递数据。具体来说,Model 接口提供了一个 addAttribute() 方法,用于将数据添加到模型中,以便在视图中使用。

使用 Spring 中的 Model 有以下好处:

  1. 简化代码:使用 Model 可以避免在控制器方法中编写大量的重复代码,如将数据存储到 HttpServletRequest 或 HttpSession 中。相反,只需调用 addAttribute() 方法一次即可将数据添加到 Model 中。

  2. 提高可读性:使用 Model 可以使代码更加清晰易懂,因为它明确指定了要传递的数据和数据的名称。

  3. 支持多种数据类型:Model 不仅支持基本数据类型,还支持集合、数组、JavaBean 等多种数据类型,可以满足不同场景下的数据传递需求。

  4. 支持多种视图技术:Model 不依赖于任何特定的视图技术,可以与多种视图技术(如 JSP、Thymeleaf 等)配合使用,从而提高应用程序的灵活性和可扩展性。

六、gitee 案例

gitee地址:ch05 · qiuqiu/SpringMVC - 码云 - 开源中国 (gitee.com)

相关文章:

SpringMVC Day 05 : Spring 中的 Model

前言 欢迎来到 SpringMVC 系列教程的第五天&#xff01;在之前的教程中&#xff0c;我们已经学习了如何使用控制器处理请求和返回视图。今天&#xff0c;我们将深入探讨 Spring 中的 Model。 在 Web 应用程序开发中&#xff0c;数据的传递和展示是非常重要的。SpringMVC 提供…...

redis6.0源码分析:字典扩容与渐进式rehash

文章目录 字典数据结构结构设计dictType字典类型为什么字典有两个哈希表&#xff1f;哈希算法 扩容机制扩容前置知识字典存在几种状态&#xff1f;容量相关的关键字段定义字典的容量都是2的幂次方 扩容机制字典什么时候会扩容&#xff1f;扩容的阈值 & 扩容的倍数哪些方法会…...

【C++迭代器iterator】

迭代器 i t e r a t o r 迭代器iterator 迭代器iterator 在 容器 v e c t o r 容器vector 容器vector 中的使用 迭代器 i t e r a t o r 迭代器iterator 迭代器iterator 一般使用在 容器 v e c t o r 容器vector 容器vector 的 遍历 遍历 遍历&#xff0c;充当 遍历指针 遍…...

基于群居蜘蛛算法的无人机航迹规划

基于群居蜘蛛算法的无人机航迹规划 文章目录 基于群居蜘蛛算法的无人机航迹规划1.群居蜘蛛搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用群居蜘蛛算法来优化无人机航迹规划。 …...

火爆全网,Python+Requests+Pytest+YAML+Allure实现接口自动化测试(附源码)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 本项目实现接口自…...

【深度学习】【NLP】如何得到一个分词器,如何训练自定义分词器:从基础到实践

文章目录 什么是分词&#xff1f;分词算法使用Python训练分词器步骤1&#xff1a;选择分词算法步骤2&#xff1a;准备训练语料步骤3&#xff1a;配置分词器参数步骤4&#xff1a;训练分词器步骤5&#xff1a;测试和使用分词器 代码示例&#xff1a;使用SentencePiece训练分词器…...

线程池的线程回收

线程池 线程池里面分为核心线程和非核心线程。 核心线程是常驻在线程池里面的工作线程&#xff0c;它有两种方式初始化&#xff1a; 向线程池里面添加任务的时候&#xff0c;被动初始化 主动调用 prestartAllCoreThreads 方法 当线程池里面的队列满了的情况下&#xff0c;为了增…...

【2023.10.25练习】数据库-函数1

任务描述 本关任务&#xff1a;编写函数fun_1完成学生选课操作。输入参数&#xff1a;学号、课程名&#xff0c;函数返回值&#xff1a;操作结果。 如果该生已有该门课程的选修记录&#xff0c;则函数返回-1&#xff1b;如果该门课程无先修课&#xff0c;则将选课信息添加到选…...

基于水循环算法的无人机航迹规划-附代码

基于水循环算法的无人机航迹规划 文章目录 基于水循环算法的无人机航迹规划1.水循环搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用水循环算法来优化无人机航迹规划。 1.水循环…...

JVM调优(10)JVM的运行时数据区

一、概述 对于 C C 来说&#xff0c;在内存管理领域&#xff0c;JVM既拥有最高的权利&#xff0c;但是同时他们又是从事最基础工作的劳动人员&#xff0c;因为他们担负着每一个对象从开始到结束的维护责任。而对于Java来说&#xff0c;再虚拟机自动内存管理的帮助下&#xff0…...

Python网络爬虫介绍

视频版教程&#xff1a;一天掌握python爬虫【基础篇】 涵盖 requests、beautifulsoup、selenium 什么是网络爬虫&#xff1f; 网络爬虫&#xff08;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追逐者&#xff09;&#xff…...

iOS QR界面亮度调整

亮度调事&#xff0c;不久在QR界面切换的时候还要考虑进入前台后台时的操作 1.QR界面功能实现代码。 QR界面- (void)viewWillAppear:(BOOL)animated {[super viewWillAppear:animated];[[NSUserDefaults standardUserDefaults] setValue:([UIScreen mainScreen].brightness) …...

Linux shell编程学习笔记17:for循环语句

Linux Shell 脚本编程和其他编程语言一样&#xff0c;支持算数、关系、布尔、字符串、文件测试等多种运算&#xff0c;同样也需要进行根据条件进行流程控制&#xff0c;提供了if、for、while、until等语句。 之前我们探讨了if语句&#xff0c;现在我们来探讨for循环语句。 Li…...

Go语言用Resty库编写的音频爬虫代码

目录 一、Go语言与Resty库简介 二、音频爬虫的实现 1、确定抓取目标 2、使用Resty发送HTTP请求 3、解析响应数据 4、下载音频文件 5、并发下载音频文件 三、注意事项 总结 随着互联网的飞速发展&#xff0c;网络爬虫逐渐成为数据获取和分析的重要工具。在音频领域&…...

AWTK 液体流动效果控件发布

液体流动效果控件。 主要特色&#xff1a; 支持水平和垂直方向。支持正向和反向流动。支持设置头尾的图片。支持设置流动的图片。支持设置速度的快慢。支持启停操作。 准备 获取 awtk 并编译 git clone https://github.com/zlgopen/awtk.git cd awtk; scons; cd -运行 生成…...

对mysql的联合索引的深刻理解

背景 对mysql的联合索引的考察是Java程序员面试高频考点&#xff01;必须深刻理解掌握否则容易丢分非常可惜。 技术难点 考察对最左侧匹配原理理解。 原理 暂且不表。网上讲这非常多。我理解就是&#xff0c;B树每个非叶子节点的值都是有序存放索引的值。 比如对A、B、C …...

C的自定义类型

目录 1. 结构体 1.1. 结构体类型的声明 1.1.1. 特殊声明 2. 结构的自引用 3. 结构体变量的定义和初始化 4. 结构体内存对齐 4.1. 结构体内存对齐 4.2. 修改默认对齐数 5. 结构体传参 6. 结构体实现位段&#xff08;位段的填充&可移植性&#xff09; 6.1. 什么是位…...

我的创作纪念日 - 2048

机缘 昨天刚刚收到 C 站的 1024 勋章&#xff1a; 今天爬山途中就又收到了 CSDN 的创作 2048 天纪念推送&#xff1a; 虽然 1024、2048 这些数字对普通人来说可能没有意义&#xff0c;但对于程序员来说却有不一样的情结。感谢 C 站这波细心的操作&#xff0c;替程序员的我们记…...

拿捏面试官,高频接口自动化测试面试题总结(附答案)狂收offer...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 面试题&#xff1…...

大数据-Storm流式框架(六)---Kafka介绍

Kafka简介 Kafka是一个分布式的消息队列系统(Message Queue)。 官网&#xff1a;Apache Kafka 消息和批次 kafka的数据单元称为消息。消息可以看成是数据库表的一行或一条记录。 消息由字节数组组成&#xff0c;kafka中消息没有特别的格式或含义。 消息有可选的键&#x…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...