SpringMVC 是 Spring 框架的一个核心模块,全称为 Spring Web MVC (Model-View-Controller),是基于 MVC 设计模式的Java Web 开发框架,用于简化 Web 应用程序的开发。
本文详细介绍了Springmvc易混淆的点,通过理解核心概念,了解mvc的发展,更深理解框架,最后编写一个demo来搭建流程
一、MVC设计模式
-
Model(模型) :负责数据封装和业务逻辑,通常是 JavaBean / 实体类(如
User、Order),用于存储处理后的数据。 -
View(视图):负责数据展示,通常是 JSP、HTML、Thymeleaf 等页面模板,用于将 Model 中的数据呈现给用户。
-
Controller(控制器):负责接收请求、协调调度(调用 Service 层处理业务),并将处理结果传递给 View 或直接返回数据(如 JSON),是请求处理的 "中枢"。
二、核心流程(请求处理步骤)
1.浏览器发送请求
2.请求被 DispatcherServlet(前端控制器,SpringMVC 的核心)拦截;
3.DispatcherServlet根据请求路径找到对应的controller方法
4.controller方法调用service层,其中service会调用dao层去访问数据库,最后生成数据Model
5.controller将视图名称和Model返回给DispatcherServlet
6.DispatcherServlet根据视图解析器将视图名称解析成前端页面
7.跳转前端页面并对Model完成渲染(页面展示)
三、session和cookie简单理解
1.session是服务端为客户端(浏览器)创建的对话容器,通常储存客户端一些信息,可理解为一个聊条框,session里面储存一个sessionID,客户端访问服务端时,就通过SessionID或者重写url来判断哪个客户端(request)
2.cookie 是客户端储存的小型文本文件,也是服务端创建的,由服务端创建并发给客户端(浏览器),浏览器接受的话,就要交接收responce,所有cookie在responce里面。
| 维度 | Session | Cookie |
|---|---|---|
| 存储位置 | 服务端(如 Tomcat 等服务器内存 / 缓存) | 客户端浏览器(本地文件) |
| 存储内容 | 存储用户的敏感 / 复杂状态信息(如登录凭证、购物车详情、用户权限等) | 存储用户的非敏感 / 标识性信息(如用户偏好、会话标识(Session ID)、广告追踪标识等) |
| 生命周期 | 默认为一次会话(浏览器关闭则失效,也可手动设置超时时间) | 可设置过期时间(如 1 天、7 天,也可设置为会话级(浏览器关闭失效)) |
| 大小限制 | 理论上无严格大小限制(受服务端资源限制) | 单个 Cookie 一般不超过 4KB,单域名下 Cookie 数量一般限制在 20~50 个 |
| 安全性 | 存储在服务端,相对安全(但需防范 Session 劫持等攻击) | 存储在客户端,易被窃取、篡改(敏感信息需加密) |
四、jsp和html对比
首先,你要知道的是现在的 Java Web 开发中,JSP 确实已经几乎被淘汰,但是jsp的原理还是值得学的!
(1) jsp是什么?jsp和html区别
jsp本质是一个servlet,浏览器请求jsp文件,服务器(servlet)会把jsp文件编译成Java servlet类,然后服务器去执行servlet类,运行java代码生成html页面,最终返给前端。
| 对比项 | HTML | JSP |
|---|---|---|
| 定义 | 纯静态的标记语言,用来描述网页的结构和内容 | 动态网页技术,本质是一个 Servlet(Java 类),需要在服务器端编译运行 |
| 文件后缀 | .html |
.jsp |
| 核心能力 | 只能展示固定的静态内容 | 可以嵌入 Java 代码、EL 表达式、JSTL 标签,动态生成内容 |
(2)jsp为什么被淘汰 ?
JSP 被淘汰的核心原因是它的设计已经跟不上现代 Web 开发的趋势,主要问题有:
- 前后端耦合严重:JSP 里混着 Java 代码、HTML、CSS、JS,前端开发人员无法独立工作,代码维护性极差;
- 容器依赖强:JSP 需要 Tomcat等 Servlet 容器编译成 Servlet 才能运行,无法适配现在的微服务、云原生部署(比如打包成 Jar 包时,JSP 路径容易出问题);
- 性能和扩展性差:JSP 每次修改都需要重启容器(开发阶段),编译后的 Servlet 也会占用容器资源;
- 不符合前后端分离趋势:现在主流是「后端提供 JSON 接口,前端(Vue/React/Angular)独立渲染 HTML」,JSP 这种服务端渲染(SSR)的方式逐渐被替代。
五、编写小demo
(1)引入依赖
<!--引入springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>7.0.2</version>
</dependency>
<!--引入Servlet-->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.1.0</version>
<scope>provided</scope>
</dependency>
(2)在web-app下配置web.xml,配置前端控制器
java
<!--配置SpringMVC的前端控制器,对浏览器发送的请求统一进行处理,也就是需要配置Servlet-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置初始化参数指定SpringMVC配置文件的位置和名称-->
<init-param>
<!--
contextConfigLocation 为固定值
初始化参数:contextConfigLocation:用来指定springMVC配置文件 在哪个路径
-->
<param-name>contextConfigLocation</param-name>
<!--classpath:表示从类路径下加载-->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--load-on-startup表示启动时加载-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--设置Servlet映射路径-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!--/代表匹配请求是所有,但不包含.jsp请求路径-->
<url-pattern>/</url-pattern>
</servlet-mapping>
(3)在resource目录下创建核心配置文件
java
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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 ">
<!--2、配置处理器映射器:BeanNameUrlHandlerMapping-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--3、配置处理器适配器:SimpleControllerHandlerAdapter-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--4、配置控制器-->
<bean id="/helloController" class="com.guan.springmvc.HelloController"/>
<!--5、配置视图解析器:InternalResourceViewResolver-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="" />
<property name="suffix" value=".jsp" />
</bean>
<!--解决 DispatcherServlet 拦截所有请求导致静态资源访问 404 的问题,需要放在扫描注解之后-->
<mvc:default-servlet-handler/>
</beans>
(4)编写controller类
java
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jspecify.annotations.Nullable;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class HelloController implements Controller {
@Override
public @Nullable ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ModelAndView :模型和视图
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg","Hello SpringMVC");
modelAndView.setViewName("index");
return modelAndView;
}
}
(5)最后启动tomcat,在浏览器输入上下文和控制器的id访问servlet。

六、DispatcherServlet和其他servlet对比
普通 Servlet:是 Java EE 规范定义的基础 Web 组件,是处理 HTTP 请求的 "最小单元",每个 Servlet 通常只负责处理一类或一个特定的请求。
DispatcherServlet :是 Spring MVC 框架的前端控制器(Front Controller),它本身也是一个 Servlet,但它是整个 Spring MVC 流程的 "调度中心",负责统一接收请求、分发请求、协调各个组件完成处理流程。
| 对比维度 | 普通 Servlet | DispatcherServlet |
|---|---|---|
| 设计定位 | 处理单个 / 一类特定请求的 "业务处理器" | 统一调度所有请求的 "前端控制器" |
| 核心职责 | 自己处理请求、生成响应(业务逻辑 + 请求响应耦合) | 统一接收请求 → 分发到 Controller → 协调组件完成处理 → 返回响应(只调度,不处理业务) |
| 请求处理方式 | 重写 doGet()/doPost() 等方法,直接在方法里写请求参数解析、业务逻辑、响应生成代码 |
不处理具体业务,通过 Spring 容器中的 HandlerMapping 找到对应 Controller,HandlerAdapter 执行方法,ViewResolver 解析视图 |
| 配置方式 | 每个 Servlet 需单独在 web.xml 配置(或 @WebServlet 注解),配置繁琐 |
只需在 web.xml 配置 1 个,后续新增功能只需添加 Controller,无需重复配置 Servlet |
| 复用性 | 通用逻辑(如参数解析、异常处理)无法复用,每个 Servlet 需重复编写 | 通用逻辑(如全局拦截、异常处理、参数绑定)通过 Spring 统一配置,所有 Controller 复用 |
| 扩展能力 | 扩展需自己手写代码,整合第三方工具成本高 | 内置丰富扩展点(拦截器、全局异常处理器、数据绑定器等),无缝整合 Spring 生态(IOC、Security 等) |
| 适用场景 | 小型、简单的 Web 应用,或需要直接控制请求全过程的场景 | 中大型 Web 应用,尤其是需要分层解耦、复用组件的 Spring MVC 项目 |
七、springMVC中流程组件分析

(1)DispatcherServlet用来统一接收请求,调用HanderMapping和HanderAdapter,最后协调ViewResolver
(2)HanderMappeing根据url找到对应的controller方法,本质就是url和controller映射表
(3)HanderAdapter主要用来统一适配不同类型的controlle。比如在我们的写代码时,有注解形式,有在SpringMVC配置文件配置bean,有实现controller接口的,HanderAdapter可以让DispatcherServlet无差别的调用Controller
还会解析url中的参数,把参数转换为controller需要的参数类型,最后把解析后的参数传递给controller
(4)controller就是逻辑层,处理对应的逻辑
(5)ViewResolver,视图解析层,比如在controller中返回index,通过配置视图解析器添加缀.jsp,将返回的物理视图名解析为物理视图路径,index - > index.jsp
八、SpringMVC处理流程

-
1.客户端发起请求 用户端(浏览器)直接向
DispatcherServlet发送 HTTP 请求(如访问hello),DispatcherServlet作为前端控制器,统一接收所有请求。 -
2.DispatcherServlet 调用 HandlerMapping 查找处理器
DispatcherServlet会调用HandlerMapping,根据请求的 URL 查找对应的处理器执行链(HandlerExecutionChain)。这个执行链包含两部分:- Handler :即具体的处理器(通常是
Controller中的某个方法) - HandlerInterceptor:对应的处理器拦截器(用于在请求前后做统一处理,如登录校验、日志记录)
- Handler :即具体的处理器(通常是
-
3.DispatcherServlet 调用 HandlerAdapter 进行处理器适配
DispatcherServlet拿到HandlerExecutionChain后,会调用HandlerAdapter。HandlerAdapter的核心作用是适配不同类型的 Handler(Controller),同时它会:- 解析请求中的参数(如 URL 参数、表单数据),转换为
Controller方法所需的参数类型 - 执行拦截器的前置处理逻辑
- 解析请求中的参数(如 URL 参数、表单数据),转换为
-
4.HandlerAdapter 执行 Controller 处理业务逻辑
HandlerAdapter调用Controller(处理器)的方法,执行业务逻辑:- 调用 Service 层、DAO 层完成数据的查询或修改
- 处理完成后,返回
ModelAndView对象(包含模型数据model和逻辑视图名viewName)
-
5.DispatcherServlet 接收 ModelAndView 并调用 ViewResolver
Controller返回的ModelAndView会先传回给DispatcherServlet,再由DispatcherServlet调用ViewResolver(视图解析器)。 -
6.ViewResolver 解析视图并返回 View 对象
ViewResolver会根据ModelAndView中的逻辑视图名 ,解析出对应的物理视图路径 (如将逻辑名hello解析为/WEB-INF/views/hello.jsp),并返回一个View对象。 -
7.View 对象渲染视图并生成响应
View对象会将ModelAndView中的模型数据填充到视图模板中(如把model中的用户数据填充到 JSP 的${user.name}标签),生成最终的 HTML 响应。 -
8.DispatcherServlet 返回响应给客户端 渲染完成的 HTML 响应会通过
DispatcherServlet返回给浏览器,用户最终看到渲染后的页面。