10 初识Spring MVC框架
约 5487 字大约 18 分钟
2025-12-25
学习目标
- 了解Spring MVC及其特点
- 掌握Spring MVC入门程序的编写
- 熟悉Spring MVC的工作原理及执行流程
在Java Web开发中,我们学习了JSP Model2架构模型,该模型采用JSP+Servlet+JavaBean技术实现了页面显示、流程控制和业务逻辑的分离。然而,JSP Model2架构模型将页面显示、流程控制等通用逻辑以硬编码方式实现,每次开发新的Web应用程序时,都需要重新编写Servlet控制器的URL分析代码以及流程控制等Web层通用逻辑代码。为解决JSP Model2架构模型在实践中存在的问题,一些基于JSP Model2架构发展起来的Web MVC应用框架应运而生。其中,Spring MVC框架是目前主流的Web MVC应用框架之一。
10.1 Spring MVC介绍
10.1.1 Spring MVC概述
在Java EE开发中,系统经典的三层架构包括表现层、业务层和持久层。三层架构中,每一层各司其职,表现层(Web层)负责接收客户端请求,并向客户端响应结果;业务层(Service层)负责业务逻辑处理,与项目需求息息相关;持久层(DAO层)负责与数据库交互,对数据库的数据进行增删改查。
Spring MVC是基于Servlet API构建的原始Web框架,属于Spring中的一个模块,正式名称是Spring Web MVC,通常被称为Spring MVC。Spring MVC 提供了对MVC 模式的全面支持,它可以将表现层进行解耦,同时,Spring MVC 是基于请求-响应处理模型的请求驱动框架,简化了表现层的实现。Spring MVC 在三层架构中的位置如图10-1所示。
从图10-1中可以看出,Spring MVC作用于三层架构中的表现层,用于接收客户端的请求并进行响应。
Spring MVC中包含了控制器和视图,控制器接收到客户端的请求后对请求数据进行解析和封装,接着将请求交给业务层处理。业务层会对请求进行处理,最后将处理结果返回给表现层。表现层接收到业务层的处理结果后,再由视图对处理结果进行渲染,渲染完成后响应给客户端。

图10-1 SpringMVC在三层架构中的位置
10.1.2 Spring MVC特点
Spring MVC能够成为目前主流的MVC框架之一,主要得益于它的以下特点:
- Spring MVC是Spring框架的后续产品,可以方便地使用Spring框架提供的其他功能
- Spring MVC使用简单,很容易设计出干净简洁的Web层
- Spring MVC支持各种请求资源的映射策略
- Spring MVC具有非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的API
- Spring MVC支持国际化,可以根据用户区域显示多国语言
- Spring MVC支持多种视图技术,包括JSP、Velocity和FreeMarker等
- Spring MVC灵活性强,易扩展
除上述特点外,Spring MVC还有很多其他特点,不再一一列举。
10.2 Spring MVC入门程序
下面将通过一个简单的入门程序演示 Spring MVC的使用。该程序要求在浏览器发起请求,由Spring MVC接收请求并响应:
10.2.1 创建项目
在IDEA中,创建一个名称为 ch10 的Maven Web项目。如果默认创建的Maven项目中没有自动生成webapp文件夹,可以在IDEA中进行设置,具体操作如下:
选择IDEA工具栏中的“File”→“Project Structure”选项,弹出“Project Structure”对话框,“Project Structure”对话框中,选择左侧菜单中的“Modules”选项,进入Modules设置界面如图所示。



选择“Web”选项进入Web设置界面,如下图所示。

在上图所示的界面中,单击“Deployment Descriptors”右侧铅笔图样的编辑按钮,弹出“Deployment Descriptor Location”对话框,如下图所示。

在图所示的对话框中,在“Web Module Deployment Descriptor(web.xml):”输入框中可以设置项目web.xml文件的路径。将路径中项目名称后的路径修改为“src/main/webapp/WEB-INF/web.xml”,然后单击“OK”按钮完成web.xml的路径设置,返回如下图所示的设置界面。

在图中单击“Web Resource Directories”右侧铅笔图样的编辑按钮,弹出“Web Resource Directory Path”对话框,如图所示。

在图所示的对话框中,在“Web resource directory path:”输入框中可以设置项目webapp文件夹的路径。将路径中项目名称后的路径修改为“src/main/webapp”,然后单击“OK”按钮完成项目webapp文件夹路径的设置。

此时,单击右下角的“OK”按钮。
至此,项目webapp文件夹相关的设置完成。项目的目录结构如图所示。

补充内容:Tomcat 本地部署及版本兼容性概述(可选)
在Java Web应用开发中,Tomcat是一个广泛使用的开源Web服务器和Servlet容器,它支持Servlet和JSP(JavaServer Pages)技术。然而,值得注意的是,Spring框架本身并不内嵌Tomcat服务器;相反,当使用Spring Boot时,可以通过添加特定的依赖项来轻松集成Tomcat作为默认的嵌入式服务器。对于非Spring Boot项目或需要更高级配置的情况,则需手动安装并配置Tomcat。
Tomcat 与 Servlet 及 JSP 版本兼容性
- Tomcat 9.x 支持Servlet 4.0规范,并且兼容JSP 2.3。
- Tomcat 8.x 系列支持Servlet 3.1规范以及JSP 2.3。
- Tomcat 7.x 支持Servlet 3.0规范及JSP 2.2。
- 更早版本的Tomcat通常支持较低版本的Servlet和JSP规范。
选择合适的Tomcat版本时,应考虑你的应用程序所依赖的Servlet API和JSP特性。例如,如果要利用Servlet 4.0的新功能如HTTP/2支持,那么至少需要使用Tomcat 9。
Servlet、JSP 与 JDK 版本兼容性
- Servlet 4.0/JSP 2.3 要求最低JDK 7。
- Servlet 3.1/JSP 2.3 同样推荐JDK 7及以上版本。
- Servlet 3.0/JSP 2.2 兼容JDK 6。
- 对于较旧的标准,如Servlet 2.5和JSP 2.1,JDK 5就已经足够了。
确保你使用的JDK版本满足上述要求是至关重要的,因为这不仅影响到编译过程,还会影响到运行时的行为。
Spring 与其他组件的版本兼容性
Spring框架与Tomcat、Servlet API以及JSP之间的兼容性主要取决于Spring版本:
- Spring Framework 5.x 官方文档建议使用Servlet 3.1+和JSP 2.3+,并且推荐基于JDK 8或更高版本构建的应用程序。
- Spring Framework 4.x 可以很好地工作于Servlet 3.0及以上版本下,同时支持JSP 2.2。
- 如果使用的是更老版本的Spring(如3.x系列),则可能需要考虑降低对Servlet和JSP版本的要求。
总之,在规划项目的技术栈时,请仔细检查各个组件间的兼容性关系,以避免潜在的问题。特别是当涉及到多版本软件共存时,确保所有组件都能够平滑地协同工作是非常重要的。此外,随着技术的发展,保持最新的库版本总是有益的,但同时也需要注意向后兼容性问题。
下载 tomcat
此处选择9.0.113 版本的 tomcat

ref:https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.113/bin/apache-tomcat-9.0.113-windows-x64.zip
配置修改防止 windows 执行 catalina.bat 脚本时控制台日志中文字符乱码:

idea 配置 tomcat
安装 smart tomcat 插件

添加本地 tomcat 实例:


10.2.2 引入Maven依赖
项目创建完成后,为保障项目的正常运行,需要导入项目所需的依赖到项目的pom.xml文件中。本项目需要使用Spring MVC和JSP,因此需要导入的依赖包括Spring核心包的依赖、Spring MVC的依赖和JSP的依赖。Spring MVC底层需要Servlet的支撑,因此还需导入Servlet的依赖。(注意版本兼容性问题)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>heima_ssm_book</artifactId>
<groupId>io.weew12.github</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ch10</artifactId>
<packaging>jar</packaging>
<name>ch10</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.3.31</spring.version>
<common.logging.version>1.2</common.logging.version>
</properties>
<dependencies>
<!-- Spring 核心类 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- jsp -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 构建-->
<build>
<!-- 设置maven tomcat 插件-->
<plugins>
<plugin>
<groupId>org.opoo.maven</groupId>
<artifactId>tomcat9-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<port>8080</port>
<path>/ch10</path>
</configuration>
</plugin>
</plugins>
</build>
</project>在文件中,配置了Spring核心类依赖、Spring MVC依赖和Servlet依赖,为Spring MVC提供运行环境;同时配置了JSP依赖,用于接收客户端请求的响应结果。
需要启动项目时,可以将项目部署到本地的Tomcat中,也可以通过Maven的Tomcat插件完成项目的启动。在<build>元素内配置了Maven的Tomcat插件。配置该插件后,**可以通过Maven指令运行Maven Web项目,而无须将项目部署到本地Tomcat中。要想在IDEA中使用插件运行Maven项目,除了需要在pom.xml文件中配置对应的插件外,还需要在IDEA中进行项目运行的相关配置。**具体配置步骤如下。
选择IDEA工具栏中的“Run”→“Edit Configurations...”选项,弹出“Run/Debug Configurations”对话框,如图所示。

在图所示的对话框中,单击左上角的“+”按钮,弹出“Add New Configurations”菜单列表,如图所示。

在图所示的菜单列表中,选择“Maven”选项,进入Maven指令的配置界面,如图所示。

在图中,“Working directory”配置的是Maven指令运行所对应的项目路径,在“Working directory”输入框中输入ch10项目在本地的路径即可。“Command line”配置的是对项目执行什么Maven指令,在此暂时只需让项目在Tomcat中运行,因此点击“OK”按钮完成配置。

10.2.3 配置前端控制器
Spring MVC 通过前端控制器拦截客户端的请求并进行转发,因此在使用Spring MVC时,配置前端控制器是必不可少的一步。Spring MVC的前端控制器也是一个Servlet,可以在项目的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">
<!-- 配置 Spring MVC 的前端控制器 -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- 配置初始化参数,用于读取 Spring MVC 的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 应用加载时创建 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>在文件中,配置了Spring MVC的前端控制器,并定义名称为DispatcherServlet。配置了<load-on-startup>元素的子元素,该配置会在项目启动时立即加载DispatcherServlet。
DispatcherServlet初始化时会加载classpath路径下的spring-mvc.xml配置文件。配置<servlet-mapping>元素的子元素内容为“/",这样在项目运行时,Spring MVC的前端控制器会拦截所有的请求URL,并交由DispatcherServlet处理。
10.2.4 配置处理器映射信息和视图解析器
在项目的resources文件夹下创建Spring MVC的配置文件spring-mvc.xml,用于配置处理器映射信息和视图解析器:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置 Spring MVC 要扫描的包 -->
<context:component-scan base-package="io.weew12.github.controller"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>在文件中,通过配置<context:component-scan>元素来扫描io.weew12.github.controller包,扫描时会将io.weew12.github.controller包下的所有处理器加载到Spring MVC中。配置了视图解析器用于解析结果视图,并将结果视图呈现给用户。其中prefix和suffix的value值分别代表查找视图页面的前缀和后缀,最终视图的地址如下:视图页面的前缀+逻辑视图名+视图页面的后缀,其中逻辑视图名需要在访问的处理器中指定。
10.2.5 创建处理器
在项目创建处理器FirstController类,用于处理客户端的请求并指定响应时跳转的页面:
package io.weew12.github.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 设置当前类为处理器类
*/
@Controller
public class FirstController {
/**
* 设定当前方法的访问映射地址
* 设置当前方法返回值类型为String:用于指定请求完成后跳转的页面
*/
@RequestMapping("/firstController")
public String sayHello() {
System.out.println("访问到 FirstController !");
// 设定具体跳转的页面
return "success";
}
}在文件中,将当前类设置为处理器类,应用程序启动时结合Spring MVC配置文件的包扫描配置,将该类注册到Spring MVC容器中;设置当前方法的访问映射地址,使用设定的“firstController”路径作为当前方法的访问地址;设定具体跳转的页面名称,结合Spring MVC配置文件,将返回值与视图解析器指定的前缀和后缀进行拼接以确定结果视图的最终路径,同时将结果解析并呈现给用户。
10.2.6 创建视图(View)页面
在项目的 WEB-INF 文件夹下创建名称为 pages 的文件夹,并在 pages文件夹下创建名称为 success 的 JSP文件,用于对客户端请求进行处理后的视图进行展示:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>FirstController</title>
</head>
<body>
<h2>Spring MVC FirstController!</h2>
</body>
</html>10.2.7 启动项目并测试应用
至此,项目的全部文件都创建完成,项目的最终目录和文件组成如图所示。

本程序使用Maven的Tomcat插件启动运行项目,前面已经讲解了 Tomcat 插件的配置。可以通过单击 IDEA菜单栏右上方的运行按钮启动项目,也可以在选中项目后使用快捷键“Shift+F10”启动项目。

项目启动成功后,在浏览器中对处理器进行请求访问,访问地址为http://localhost:8080/ch10/firstController ,访问后,浏览器跳转到的success.jsp 页面中。浏览器跳转的页面如图所示。

10.3 Spring MVC工作原理
在入门程序的实现过程中使用了Spring MVC的一些组件,为了更好地理解Spring MVC执行流程,在此先对Spring MVC的三大组件进行讲解,这三大组件分别是处理器映射器(HandlerMapping)、处理器适配器(HandlerAdapter)和视图解析器(ViewResolver)。各组件的具体作用和含义如下所示。
- 处理器映射器处理器映射器可以理解为一个
Map<URL,Handler>,HandlerMapping负责根据用户请求的URL找到Handler(处理器),Spring MVC提供了不同的映射器来实现不同的映射方式。 - 处理器适配器 处理器适配器的作用是根据处理器映射器找到的Handler信息,去执行相关的Handler。不同的处理器映射器映射出来的Handler对象是不一样的,不同的映射由不同的适配器来负责解析。
- 视图解析器视图解析器进行视图解析时,首先将逻辑视图名解析成物理视图名,即具体的页面地址,再生成View视图对象返回。
Spring MVC 的三大组件是Spring MVC 的执行流程中的重要节点,在学习完 Spring MVC 的三大组件的作用后,接着进一步学习 Spring MVC的执行流程。Spring MVC的执行流程如图10-14 所示。

图10-14 SpringMVC的执行流程
下面结合图10-14对Spring MVC的执行流程进行详细介绍。
(1)用户通过浏览器向服务器发送请求,请求会被Spring MVC的前端控制器(DispatcherServlet)拦截。
(2)DispatcherServlet拦截到请求后,会调用处理器映射器(HandlerMapping)。
(3)处理器映射器根据请求URL找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
(4)DispatcherServlet会通过返回信息选择合适的处理器适配器(HandlerAdapter)。
(5)HandlerAdapter会调用并执行处理器(Handler),这里的处理器是指程序中编写的Controller类,也被称之为后端控制器。
(6)Controller执行完成后,会返回一个ModelAndView对象,该对象中会包含视图名或包含模型和视图名。
(7)HandlerAdapter将ModelAndView对象返回给DispatcherServlet。
(8)前端控制器请求视图解析器根据逻辑视图名解析真正的视图。
(9)ViewResolver解析后,会向DispatcherServlet中返回具体的视图(View)对象。
(10)DispatcherServlet 对View进行渲染(即将模型数据填充至视图中)。
(11)前端控制器向用户响应结果。
在上述执行过程中,DispatcherServlet、HandlerMapping、HandlerAdapter 和 ViewResolver对象的工作是在框架内部执行的,开发人员只需要配置前端控制器(DispatcherServlet),完成Controller中的业务处理并在视图(View)中展示相应信息即可。
提示:
在老版本的Spring MVC中,配置文件内必须要配置处理器映射器、处理器适配器和视图解析器,但在Spring 4.0版本后,如果不配置处理器映射器、处理器适配器和视图解析器,框架会加载内部默认的配置完成相应的工作。如果想显式并快捷地配置处理器映射器和处理器适配器,也可修改在配置文件中使用<mvc:annotation-driven>元素来实现,该元素会自动注册处理器映射器和处理器适配器。
10.4 本章小结
本章主要对Spring MVC的基础知识进行了整体介绍。首先对Spring MVC框架进行了简单介绍;然后讲解了一个Spring MVC入门程序的编写;最后通过入门程序对Spring MVC的工作原理进行了详细讲解。通过学习本章的内容,能够了解什么是 Spring MVC,以及 Spring MVC的优点、Spring MVC入门程序的编写、并熟悉Spring MVC框架的工作流程。
【思考题】
- 请简述Spring MVC框架的优点。
Spring MVC(Model-View-Controller)是Spring框架中用于构建Web应用程序的一个模块,它提供了一种清晰的方式来分离应用程序的不同方面(输入逻辑、业务逻辑和UI逻辑),从而支持松耦合的开发模式。以下是Spring MVC框架的一些主要优点:- 高度可配置性:Spring MVC允许开发者通过XML或注解灵活地配置应用组件,使得程序结构更加清晰易懂。
- 松散耦合:遵循MVC设计模式,将数据访问、业务处理以及用户界面展示分离开来,提高了代码重用性和测试效率。
- 强大的视图解析器:内置了多种视图技术的支持如JSP, Thymeleaf, FreeMarker等,并且很容易集成其他模板引擎。
- 异常处理机制:提供了全局异常处理器,可以统一管理并优雅地处理系统中的各类错误信息。
- 灵活性与扩展性:易于与其他Spring生态系统下的项目进行整合,比如Spring Security以增强安全性,或是Spring Data简化数据库操作等。
- 国际化支持:内置了对多语言环境的良好支持,方便实现网站内容的本地化。
- RESTful风格的服务开发:非常适用于创建RESTful Web服务,支持JSON/XML格式的数据传输。
- 请简述Spring MVC框架的工作执行流程。
Spring MVC的工作流程主要包括以下几个步骤:- 请求到达:客户端发起HTTP请求到服务器端。
- DispatcherServlet拦截:所有传入的请求首先由前端控制器
DispatcherServlet接收。它是整个过程的核心组件,负责调度请求至相应的处理器。 - HandlerMapping映射:
DispatcherServlet根据请求URL查找对应的处理器映射(HandlerMapping),确定应该调用哪个控制器(Controller)来处理该请求。 - Controller处理:找到合适的处理器后,
DispatcherServlet将请求转发给选定的控制器方法。在这里,实际的业务逻辑被执行。 - 返回ModelAndView:控制器完成逻辑处理后,会返回一个
ModelAndView对象给DispatcherServlet。这个对象包含了模型数据(Model)及视图名称(View)。 - ViewResolver解析:
DispatcherServlet使用视图解析器(ViewResolver)来解析从控制器返回的视图名,将其转换为具体的视图对象。 - 渲染页面:最后,视图对象被用来渲染最终的HTML页面,其中可能包含之前设置的模型数据。
- 响应发送:渲染完毕后的响应结果被发送回客户端浏览器显示。
