目录
4.SpringMVC,Spring,和SpringBoot的关系:
[二、SpringMVC 快速入门](#二、SpringMVC 快速入门)
[1.浏览器使用 URL 发出 HTTP请求:](#1.浏览器使用 URL 发出 HTTP请求:)
[2.前端控制器 调用 处理器映射器:](#2.前端控制器 调用 处理器映射器:)
[3.处理器映射器返回 处理器执行链:](#3.处理器映射器返回 处理器执行链:)
[5.处理器适配器 调用 Handler:](#5.处理器适配器 调用 Handler:)
[6.Handler 返回数据给 处理器适配器:](#6.Handler 返回数据给 处理器适配器:)
[7.处理器适配器 继续将数据返回给 前端控制器:](#7.处理器适配器 继续将数据返回给 前端控制器:)
[8.前端控制器 调用 视图解析器:](#8.前端控制器 调用 视图解析器:)
[9.视图解析器 将解析后的结果返回给 前端控制器:](#9.视图解析器 将解析后的结果返回给 前端控制器:)
[10.通过具体的 视图技术(View)进行视图渲染:](#10.通过具体的 视图技术(View)进行视图渲染:)
[11.前端控制器 返回 HTTP响应 给浏览器:](#11.前端控制器 返回 HTTP响应 给浏览器:)
[Δ总览 / 总结 SpringMVC的执行流程(一张全景图):](#Δ总览 / 总结 SpringMVC的执行流程(一张全景图):)
一、拾枝杂谈
1.MVC的定义:
(1) MVC,分别是指Model(模型),View(视图),Controller(控制器)------
++Model++ : 将与业务逻辑相关的数据封装 为具体的 JavaBean类(JavaBean/Domain/POJO),其中不掺杂任何与数据处理相关的代码。
++View++ : 只负责数据和界面的显示,不接受任何与显示 数据无关的代码,便于程序员和美工的分工合作。(Vue/Jsp/Thymeleaf/HTML)。
++Controller++ : 只负责接收请求,调用Service层的代码处理请求,然后派发页面,起到"调度者 "的作用。(2) MVC最早出现于 JavaEE三层架构 中的 Web层 ,可以指导Web层的代码实现有效分离,单独工作,其本质就是将软件代码拆分成为组件单独开发,组合使用,达到了解耦 的目的。MVC是一种思想,体现的是 数据显示 ,数据处理 和 业务调用的分离解耦。SpringMVC就是一种基于MVC思想的 WEB层框架。
(3) JavaEE三次架构如下图所示:
(4) MVC 是设计模式 ,聚焦于表现层(Web 层)的职责分离(Model-View-Controller)。Service 层和 DAO 层是分层架构,属于业务逻辑层和数据访问层,与 MVC 中的 "Model" 对应。
MVC思想在web层的应用如下图所示:
2.SpringMVC概述:
(1) SpringMVC 是基于 Spring 的web层框架 ,即SpringMVC 接管了 WEB层组件(例如控制器,视图,视图解析等)。
(2) SpringMVC 的核心jar包是 spring-webmvc-xx.jar 和 spring-web.xx.jar, 在 Spring 的libs目录下可以找到。如下图所示:
3.SpringMVC特点:
(1) SpringMVC 支持 REST格式的 URL 请求。
(2) SpringMVC 采用 低耦合的组件设计方式,具有更好的扩展性和灵活性。
(3) SpringMVC 通过 注解即可让POJO成为Controller,而不必像原生WEB开发一样去继承一个类(如HttpServlet)或者去实现接口。
4.SpringMVC,Spring,和SpringBoot的关系:
(1) SpringMVC 只是 Spring 中负责处理 WEB层 请求的 一个模块/组件,SpringMVC的底层是Servlet(传统的JavaWeb开发)。
(2) SpringBoot 是为了帮助开发者简化Java开发,而推出的牛逼框架(约定优于配置),简化了Spring的配置流程,SpringBoot中包含有很多Spring的组件,可以说Spring就是其最核心的内容之一,当然也就包含了SpringMVC。
二、SpringMVC 快速入门
1.引入依赖:
创建一个新的 Java 项目,并引入 Web Application 支持,如下图所示:

然后在 WEB-INF/lib 目录下,导入所有需要的 jar 包,如下图所示:

2.配置中央控制器和视图解析器:
下一步在 web.xml 中配置一个 中央控制器(也叫前端控制器),用于处理所有的应用请求(后面会讲到中央控制器)。web.xml 配置如下:
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>mvcDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 通过 contextConfigLocation 指定 DispatcherServlet -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvcDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
<!--
url-pattern == /, 表示所有的用户请求都会经过 DispatcherServlet, 且支持Rest风格。
-->
</servlet-mapping>
</web-app>
如果不在 web.xml 指定 applicationContext-mvc.xml, 默认在**/WEB-INF/springDispatcherServlet-servlet.xml** 找这个配置文件。
除了在 web.xml 中配置 中央控制器(DispatcherServlet),现在还需要配置 视图解析器 ,视图解析器被配置在 Spring 的xml配置文件中,为了特意标识 SpringMVC,up将其命名为applicationContext-mvc.xml,代码如下:
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"
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="com.cyan.web"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--
视图解析器需要配置两个属性------prefix(前缀) 和 suffix(后缀),
视图解析器收到Servlet的 "return "login_OK";" 时,会用prefix和suffix与返回的资源名拼接。
-->
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 激活注解(开启 Spring MVC 注解驱动) -->
<mvc:annotation-driven/>
</beans>
3.搭建简单的前后端业务:
为了演示SpringMVC 对Web层的接管,我们需要先创建一个简单的 登陆页面 ,然后通过登录页面的 表单 发起请求,并在后端的 Servlet 中进行请求的处理和返回。login.jsp 代码如下:
html
<%--
User : Cyan_RA9
Version : 21.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Sign In</title>
</head>
<body>
<h2 style="alignment: center">Sign In Page</h2>
<%-- 回顾:这里的action前面为什么不能带/ --%>
<%-- 更稳健的写法------<form action="${pageContext.request.contextPath}/login"> --%>
<form action="login">
<table border="1" cellspacing="0" cellpadding="10">
<tr>
<th colspan="2">Sign In</th>
</tr>
<tr>
<td>username: </td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>password: </td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td><input type="submit" value="submit"/></td>
<td><input type="reset" value="reset"/></td>
</tr>
</table>
</form>
</body>
</html>
login.jsp 页面效果图如下:(需要配置好 Tomcat)

后端用于处理 "用户登录" 请求的 UserServlet 代码如下:
java
package com.cyan.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author : Cyan_RA9
* @version : 22.0
*/
@Controller //@Controller注解,标识当前类是一个控制器,有时也称为Handler(处理器)
public class UserServlet {
/*
1. @RequestMapping 的 value 表示该方法的url映射,即当用户在浏览器地址栏输入
http://localhost:8080/web工程路径/login 时,就可以访问到login()方法。
2. return "login_OK",表示返回结果给视图解析器(InternalResourceViewResolver)
,视图解析器会根据配置,来决定跳转到哪个页面。
*/
@RequestMapping(value = "/login") //此处的value可以省略
public String login() {
System.out.println("Successfully log in");
return "login_OK";
}
}
由 UserServlet 的代码可以看出,还需要再来一个 login_OK.jsp 页面,代码如下:
html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login_OK</title>
</head>
<body>
<h1>Sign In Successfully!</h1>
</body>
</html>
login_OK.jsp 页面效果图如下:(需要配置好 Tomcat)

此时的 WEB 工程目录结构,如下图所示:

4.运行测试:
测试结果如下GIF图所示:

三、SpringMVC执行流程分析
1.浏览器使用 URL 发出 HTTP请求:
浏览器解析URL后,向服务器发出HTTP请求,如下图所示:

2.前端控制器 调用 处理器映射器:
服务器端的 前端控制器 进一步去调用 处理器映射器,如下图所示:

3.处理器映射器返回 处理器执行链:
处理器映射器 会返回 处理器执行链,具体包括多个 拦截器 和要调用的 处理器,如下图所示:

4.前端控制器继续调用处理器适配器:
服务器端的 前端控制器 为了获得需要的Handler,再去调用处理器适配器(需要处理器适配器的帮助),如下图所示:

5.处理器适配器 调用 Handler:
处理器适配器 才是真正去调用 Handler 的那个东西,而 Handler 会执行我们自己的业务逻辑,即Service,DAO那一套。如下图所示:

6.Handler 返回数据给 处理器适配器:
处理器执行完毕业务逻辑后,会返回 ModelAndView,包括了用户数据 和 指定的要转发的View。如下图所示:

7.处理器适配器 继续将数据返回给 前端控制器:
处理器适配器 收到 Handler 发回的数据后,并不会进行对应的处理,而是会将数据继续返回给最开始的 前端控制器。如下图所示:

8.前端控制器 调用 视图解析器:
前端控制器 收到 处理器适配器 返回的ModelAndView之后,会调用配置好的 视图解析器 来查找并渲染最终的视图,也就是我们在 Spring 的配置文件中配置的 InternalResourceViewResolver。如下图所示:

9.视图解析器 将解析后的结果返回给 前端控制器:
视图解析器 收到 前端控制器 传来的逻辑视图名后,会根据自身配置的规则(例如前缀、后缀、视图技术类型),将逻辑视图名解析成一个具体的视图实现(例如 JstlView、ThymeleafView 等)以及其物理位置(例如 /WEB-INF/views/userList.jsp),并最终返回给 前端控制器。如下图所示:

10.通过具体的 视图技术(View)进行视图渲染:
前端控制器 命令 视图解析器 去协调具体的视图技术 对视图进行渲染。具体视图(View)是真正执行渲染操作的组件。它封装了特定的视图技术(如 JSP、Thymeleaf、FreeMarker 等)的渲染逻辑。如下图所示:

11.前端控制器 返回 HTTP响应 给浏览器:
在拿到最终渲染后的视图后,前端控制器会将结果打包成HTTP响应并返回给浏览器,如下图所示:

Δ总览 / 总结 SpringMVC的执行流程(一张全景图):
将之前的所有步骤合并为一张图,如下所示:

Δ总结
- 🆗,以上就是文章的全部内容了😀。
- 这算是 SpringMVC 的一篇入门文章,一开始做了一个入门案例。文章主体还是后面的 "图解SpringMVC执行流程"部分。大家也可以跟着up一起画一画。