前言
欢迎来到 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 的初始化和请求映射。
具体来说,这段配置的作用如下:
- 定义了一个名为 "dispatcher" 的 Servlet,并指定了 org.springframework.web.servlet.DispatcherServlet 作为其处理类。
- 设置了 load-on-startup 属性为 1,表示在应用启动时就加载该 Servlet。
- 使用 <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框架进行开发。
具体来说,该配置文件包含以下几个部分:
命名空间声明:声明了XML文件所使用的命名空间,包括beans、context和mvc三个命名空间。
组件扫描:通过context:component-scan标签启用组件扫描机制,指定需要扫描的包路径,以便Spring MVC框架能够自动扫描和注册相关的组件。
注解驱动:通过mvc:annotation-driven标签启用注解驱动机制,使得Spring MVC框架能够自动识别和处理控制器中的注解,例如@RequestMapping、@ResponseBody等。
静态资源处理:通过mcv:default-servlet-handler标签配置默认的servlet处理静态资源,以便在Web应用中访问静态资源,例如图片、CSS、JavaScript等。
视图解析器:通过<bean>标签配置视图解析器,将JSP页面映射到对应的控制器方法上,以便返回相应的视图。
二、将 map 设置到 ModelAndView 中
@Controller
public class ModelController {
@GetMapping("/test1")
public ModelAndView test1() {
ModelAndView mav = new ModelAndView("index");
// 设置请求作用域
mav.addObject("name", "qiu");
// 也可以将数据保存到 map 集合中,再设置列到 ModelAndView
Map<String, Object> map = new HashMap<>();
map.put("age", 21);
// 再将 map 设置到 ModelAndView 中
mav.addAllObjects(map);
return mav;
}
}
这段代码的意思是:
使用了
@GetMapping("/test1")
注解来处理 GET 请求,并将请求映射到路径 "/test1"。该方法返回一个
ModelAndView
对象,并设置视图名称为 "index"。使用
mav.addObject()
方法将参数保存到请求作用域中,参数名作为键,参数值作为值。在这个例子中,将 "name" 设置为 "qiu"。还可以将数据保存到一个
Map
集合中,并使用mav.addAllObjects()
方法将整个Map
设置到ModelAndView
中。在这个例子中,将 "age" 设置为 21。最后,将数据保存到请求作用域中,并将视图名称设置为 "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 传递参数的区别:
数据封装方式:原生 Servlet 需要手动从 HttpServletRequest 中获取参数,并进行解析和封装;而使用 Spring 的 Model 则是通过调用 addAttribute() 方法将数据添加到 Model 中,Spring 框架会自动将数据传递给视图。
数据范围:原生 Servlet 的参数传递范围局限于单个请求,参数只能在当前请求中传递;而使用 Spring 的 Model,数据可以在整个请求处理过程中共享,包括请求转发、重定向等情况下都可以传递数据。
视图解析:原生 Servlet 需要手动编写代码来进行视图解析,如使用 RequestDispatcher 进行请求转发或设置响应结果;而使用 Spring 的 Model,则由 Spring MVC 框架负责解析视图,根据配置的视图解析器将模型数据渲染到相应的视图上。
框架集成:原生 Servlet 是 Java EE 标准的一部分,可以与其他 Java EE 技术无缝集成;而使用 Spring 的 Model,需要结合 Spring MVC 框架进行使用,可以充分利用 Spring 提供的各种便利功能,如拦截器、AOP 等。
总的来说,使用 Spring 的 Model 传递参数相对于原生 Servlet 更加简洁、方便,并且能够与 Spring MVC 框架的其他功能无缝集成。它提供了一种高级的数据传递方式,使得开发人员能够更加专注于业务逻辑的实现,而不需要过多关注底层的参数解析和视图解析等细节。
五、使用 Spring 中的 Model 有什么好处
在 Spring 中,Model 是一个接口,它允许控制器方法向视图传递数据。具体来说,Model 接口提供了一个 addAttribute() 方法,用于将数据添加到模型中,以便在视图中使用。
使用 Spring 中的 Model 有以下好处:
简化代码:使用 Model 可以避免在控制器方法中编写大量的重复代码,如将数据存储到 HttpServletRequest 或 HttpSession 中。相反,只需调用 addAttribute() 方法一次即可将数据添加到 Model 中。
提高可读性:使用 Model 可以使代码更加清晰易懂,因为它明确指定了要传递的数据和数据的名称。
支持多种数据类型:Model 不仅支持基本数据类型,还支持集合、数组、JavaBean 等多种数据类型,可以满足不同场景下的数据传递需求。
支持多种视图技术:Model 不依赖于任何特定的视图技术,可以与多种视图技术(如 JSP、Thymeleaf 等)配合使用,从而提高应用程序的灵活性和可扩展性。
六、gitee 案例
gitee地址:ch05 · qiuqiu/SpringMVC - 码云 - 开源中国 (gitee.com)