Spring 核心技术解析【纯干货版】- XVI:Spring 网络模块 Spring-WebMvc 模块精讲
在现代 Web 开发中,高效、稳定、可扩展的框架至关重要。Spring WebMvc 作为 Spring Framework 的核心模块之一,为开发人员提供了强大的 MVC 体系支持,使得 Web 应用的构建更加便捷和规范。无论是传统的 JSP 视图渲染,还是基于 RESTful 的 API 设计,Spring WebMvc 都能提供完善的解决方案。
本篇文章将深入解析 Spring WebMvc 模块的核心概念、依赖关系、组件架构及其应用场景,并通过一个完整的示例,帮助读者理解如何使用 Spring WebMvc 构建高效的 Web 应用。希望通过本篇内容,让你能更加熟练地掌握 Spring MVC 及其实践应用。
文章目录
- 1、Spring WebMvc 模块介绍
- 1.1、Spring WebMvc 模块概述
- 1.2、Spring WebMvc 模块依赖
- 1.3、Spring WebMvc 模块作用
- 1.4、Spring WebMvc 核心组件说明
- 2、关于 MVC 模式
- 3、Spring MVC 案例:使用 Spring Web 进行 RESTful API 调用
- 3.1、项目结构
- 3.2、配置 web.xml
- 3.3、配置 Spring MVC
- 3.4、创建模型 (Model)
- 3.5、创建服务层 (Service)
- 3.6、创建控制器 (Controller)
- 3.7、创建视图 (JSP)
- 3.8、 运行项目
- X、后记
1、Spring WebMvc 模块介绍
1.1、Spring WebMvc 模块概述
Spring WebMvc 是 Spring Framework 的核心模块之一,专门用于构建基于 MVC(Model-View-Controller)设计模式的 Web 应用程序。作为 Spring 对 Servlet API 的封装实现,它通过清晰的职责划分和高效的请求处理机制,简化了传统同步 Web 应用及 REST API 的开发流程。
该模块的核心特性包括:
- 注解驱动开发:通过
@Controller、@RestController、@RequestMapping等注解实现请求路由与处理。 - 视图解析与渲染:支持 JSP、Thymeleaf、FreeMarker 等多种视图技术。
- 数据绑定与校验:自动封装请求参数到对象,集成 Hibernate Validator 等校验框架。
- 拦截器与过滤器:通过
HandlerInterceptor实现预处理和后处理逻辑。 - 异常统一处理:支持全局异常处理机制(
@ControllerAdvice)和自定义错误页面。 - RESTful 支持:通过
@RequestBody、@ResponseBody实现 JSON/XML 数据交互。
Spring WebMvc 遵循 “约定优于配置” 原则,既能通过 XML 配置实现传统开发模式,也可借助 Spring Boot 实现零配置快速启动,广泛应用于企业级 Web 应用开发。
1.2、Spring WebMvc 模块依赖
Spring WebMvc 的底层实现依赖于以下 Spring 核心模块:
| 模块 | 作用 |
|---|---|
| Spring Core | 提供 IOC 容器、资源加载、类型转换等基础功能,是框架的基石。 |
| Spring Beans | 管理 Bean 的生命周期、依赖注入(DI),支持 @Autowired 等注解。 |
| Spring Context | 扩展 Core 模块,提供国际化、事件传播、AOP 集成等企业级特性。 |
| Spring AOP | 支持面向切面编程,实现事务管理、日志记录等横切关注点。 |
| Spring Web | 提供基础的 Web 功能(如 Multipart 文件上传),是 WebMvc 的前置依赖。 |
| Spring Expression (SpEL) | 支持运行时表达式解析,用于动态绑定请求参数、条件路由等场景。 |
注:在 Maven/Gradle 项目中,直接引入 spring-webmvc 依赖会自动关联上述模块。此外,实际开发中常需集成 spring-jdbc(数据库访问)、spring-security(安全控制)等扩展模块。
1.3、Spring WebMvc 模块作用
核心作用:
-
请求处理流水线基于
DispatcherServlet的前端控制器模式,将 HTTP 请求分发给对应的 Controller,处理流程包括:- 路由匹配(
HandlerMapping) - 参数绑定(
DataBinder) - 业务逻辑执行(
Controller) - 视图渲染(
ViewResolver) - 异常处理(
HandlerExceptionResolver)
- 路由匹配(
-
分层架构支持: Model:通过 POJO 或
Model对象封装业务数据。View:解耦视图技术,支持模板引擎或静态页面。Controller:集中处理用户请求,协调业务逻辑与数据呈现。 -
扩展性与兼容性 :可集成第三方组件(如 Spring Security、Swagger)。兼容 Servlet 3.0+ 规范,支持异步请求处理(
DeferredResult/Callable)。
1.4、Spring WebMvc 核心组件说明
Spring WebMvc 下述组件的协同工作,Spring WebMvc 实现了高度可定制化的 Web 开发框架,兼顾灵活性与开发效率:
DispatcherServlet:中央调度器,协调各组件完成请求处理生命周期。HandlerMapping:根据 URL 匹配对应的 Controller 方法。HandlerAdapter:适配不同处理器类型(如@Controller、Servlet)。ViewResolver:将逻辑视图名解析为具体视图实现(如 JSP 页面)。MultipartResolver:处理文件上传请求。LocaleResolver:支持国际化与本地化。
2、关于 MVC 模式
MVC(Model-View-Controller) 是一种 软件架构模式,用于分离应用的业务逻辑、数据管理和用户界面,提高代码的可维护性和可扩展性。
MVC 的三个部分:
-
Model(模型)—— 负责数据和业务逻辑:负责存储、处理和管理数据(如数据库操作)。不直接与视图交互,而是通过控制器提供数据。例子:在 Spring MVC 中,
@Service和@Repository处理业务逻辑和数据库访问。 -
View(视图)—— 负责展示数据:负责向用户显示数据,通常是 HTML、JSP、Thymeleaf、React/Vue 等前端技术。不能直接操作 Model,而是通过 Controller 访问数据。例子:在 Spring MVC,JSP、Thymeleaf 或者 JSON 数据可以作为视图。
-
Controller(控制器)—— 负责处理请求:接收用户请求,调用 Model 处理业务逻辑,并返回数据给 View。控制器负责 路由、参数解析、返回数据。例子:在 Spring MVC,
@Controller或@RestController处理 HTTP 请求。
MVC 的工作流程:
- 用户在浏览器输入
http://localhost:8080/users,请求被 Controller 接收。 - Controller 调用 Model 处理业务逻辑(如查询数据库)。
- Model 返回数据给 Controller,然后 Controller 将数据传递给 View。
- View 生成 HTML 页面,并返回给用户。
MVC 的优点:
- 低耦合:Model、View、Controller 彼此独立,可以单独修改某一部分,而不会影响其他部分。
- 可维护性强:业务逻辑和 UI 分离,代码更容易管理和扩展。
- 适用于多种视图层:一个后端可以支持多个前端(如 Web、移动端)。
3、Spring MVC 案例:使用 Spring Web 进行 RESTful API 调用
3.1、项目结构
spring-mvc-demo/
├── src/main/java/com/example/controller/UserController.java
├── src/main/java/com/example/model/User.java
├── src/main/java/com/example/service/UserService.java
├── src/main/java/com/example/config/WebConfig.java
├── src/main/webapp/WEB-INF/views/
│ ├── users.jsp
│ ├── user.jsp
├── src/main/webapp/WEB-INF/web.xml
├── pom.xml
3.2、配置 web.xml
Spring MVC 需要在 web.xml 中配置 DispatcherServlet 作为前端控制器: src/main/webapp/WEB-INF/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"version="3.0"><!-- 配置 Spring MVC 的前端控制器 --><servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring-mvc-config.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 配置字符编码 --><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>
3.3、配置 Spring MVC
src/main/webapp/WEB-INF/spring-mvc-config.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 启用 Spring MVC 注解 --><mvc:annotation-driven/><!-- 组件扫描 --><context:component-scan base-package="com.example"/><!-- 视图解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/"/><property name="suffix" value=".jsp"/></bean></beans>
3.4、创建模型 (Model)
src/main/java/com/example/model/User.java
package com.example.model;public class User {private Long id;private String name;private String email;public User() {}public User(Long id, String name, String email) {this.id = id;this.name = name;this.email = email;}public Long getId() { return id; }public void setId(Long id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public String getEmail() { return email; }public void setEmail(String email) { this.email = email; }
}
3.5、创建服务层 (Service)
src/main/java/com/example/service/UserService.java
package com.example.service;import com.example.model.User;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;
import java.util.Optional;@Service
public class UserService {private final List<User> users = new ArrayList<>();public UserService() {users.add(new User(1L, "张三", "zhangsan@example.com"));users.add(new User(2L, "李四", "lisi@example.com"));}public List<User> getAllUsers() {return users;}public Optional<User> getUserById(Long id) {return users.stream().filter(user -> user.getId().equals(id)).findFirst();}public void addUser(User user) {users.add(user);}
}
3.6、创建控制器 (Controller)
src/main/java/com/example/controller/UserController.java
package com.example.controller;import com.example.model.User;
import com.example.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;import java.util.List;@Controller
@RequestMapping("/users")
public class UserController {private final UserService userService;public UserController(UserService userService) {this.userService = userService;}@GetMappingpublic String getAllUsers(Model model) {List<User> users = userService.getAllUsers();model.addAttribute("users", users);return "users";}@GetMapping("/{id}")public String getUserById(@PathVariable Long id, Model model) {userService.getUserById(id).ifPresent(user -> model.addAttribute("user", user));return "user";}@PostMappingpublic String addUser(@ModelAttribute User user) {userService.addUser(user);return "redirect:/users";}
}
3.7、创建视图 (JSP)
src/main/webapp/WEB-INF/views/users.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>用户列表</title>
</head>
<body><h2>用户列表</h2><ul><c:forEach var="user" items="${users}"><li><a href="users/${user.id}">${user.name}</a></li></c:forEach></ul>
</body>
</html>
src/main/webapp/WEB-INF/views/user.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>用户详情</title>
</head>
<body><h2>用户详情</h2><p>姓名: ${user.name}</p><p>邮箱: ${user.email}</p><a href="/users">返回列表</a>
</body>
</html>
3.8、 运行项目
使用 Tomcat 部署,或者在 IDE 中运行:
mvn tomcat7:run
然后访问:
http://localhost:8080/users获取所有用户http://localhost:8080/users/1获取特定用户信息
X、后记
Spring WebMvc 模块是构建现代 Web 应用的重要基石,它提供了清晰的架构分层,使开发者能够专注于业务逻辑,而无需过多关注底层的请求处理细节。通过 DispatcherServlet 这一核心组件,Spring WebMvc 实现了从请求到视图渲染的完整流程,并结合 Spring 的强大生态系统,提供了丰富的扩展能力。
本篇文章从基础概念到实际应用,系统地介绍了 Spring WebMvc 的核心功能,希望能为你的 Web 开发提供实用的指导。在实际开发中,建议结合 Spring Boot 进行整合,以实现更快速的配置和开发。如果你对 Web 开发有更深入的需求,可以进一步探索 Spring Security、Spring Cloud 等相关技术,不断提升自身的技术能力。
愿你的开发之旅更加高效顺畅!
相关文章:
Spring 核心技术解析【纯干货版】- XVI:Spring 网络模块 Spring-WebMvc 模块精讲
在现代 Web 开发中,高效、稳定、可扩展的框架至关重要。Spring WebMvc 作为 Spring Framework 的核心模块之一,为开发人员提供了强大的 MVC 体系支持,使得 Web 应用的构建更加便捷和规范。无论是传统的 JSP 视图渲染,还是基于 RES…...
【GPT入门】第33课 从应用场景出发,区分 TavilyAnswer 和 TavilySearchResults,代码实战
【GPT入门】第33课 从应用场景出发,区分 TavilyAnswer 和 TavilySearchResults,代码实战 1. 区别应用场景 2. 代码使用3.代码执行效果 在langchain_community.tools.tavily_search中,TavilyAnswer和TavilySearchResults有以下区别和应用场景&…...
JS dom修改元素的style样式属性
1通过样式属性修改 第三种 toggle有就删除 没就加上...
灭火器离位检测:智能视觉守护安全
利用视觉分析实现明火检测:技术、功能与应用 一、背景 清明节期间,兰州市连续发生多起因祭祖烧纸引发山火的警情,如七里河区魏岭乡赵某某等人上坟烧纸未妥善处理烛火引燃杂草,导致3人烧伤;七里河区彭家坪石板山村村民…...
网络:华为数通HCIA学习:IP路由基础
华为HCIA学习 IP路由基础路由协议或路由种类以及对应路由的优先级按工作区域分类:按工作机制及算法分类:路由的优先级路由器选择最优路由的顺序是什么? 前言自治系统LAN和广播域路由选路IP路由表路由度量建立路由表最长匹配原则路由器转发数据包总结 IP…...
多线程开发中List的使用
由于ArrayList在多线程高并发情况下是不安全的,因此要慎用,那么此时如果涉及到集合操作,应该怎么选: 方案一:Vector: 特点:通过给所有方法都用 synchronized 修饰从而保证线程安全, 缺点&…...
使用 .NET 9 和 Azure 构建云原生应用程序:有什么新功能?
随着 .NET 9 推出一系列以云为中心的增强功能,开发人员拥有比以往更多的工具来在 Azure 上创建可扩展、高性能的云原生应用程序。让我们深入了解 .NET 9 中的一些出色功能,这些功能使构建、部署和优化云应用程序变得更加容易,并附有示例以帮助…...
前端页面鼠标移动监控(鼠标运动、鼠标监控)鼠标防抖处理、mousemove、debounce()、事件停止触发、超时触发
文章目录 代码使用lodashjs库debounce函数做防抖处理(只有鼠标移动停止并超过一定时间,才会触发)手写防抖函数写法1写法2(注意addEventListener监听函数的第二个参数接收的是一个函数,需要构造一个匿名返回函数&#x…...
开源守护,智护童年——幼儿园未成年行为与安全智能监控系统
在孩子成长的每一步,安全始终是第一位的。幼儿园作为孩子们探索世界的起点,其安全管理的重要性不言而喻。然而,哭闹、打闹、意外跌倒,甚至外部隐患如陌生人逗留、内部管理疏漏等问题,常常让传统人工监控捉襟见肘。家长…...
WinForm真入门(5)——控件的基类Control
控件的基类–Control 用于 Windows 窗体应用程序的控件都派生自 Control类并继承了许多通用成员,这些成员都是平时使用控件的过程最常用到的。无论要学习哪个控件的使用,都离不开这些基本成员,尤其是一些公共属性。由于 Conlrol 类规范了控件的基本特征…...
《Linux内存管理:实验驱动的深度探索》【附录】【实验环境搭建 4】【Qemu 如何模拟numa架构】
我们在学习 linux 内核时,会涉及到很多 numa 的知识,那我们该如何在 qemu 中模拟这种情况,来配合我们的学习呢? 我们该如何模拟 如下的 numa 架构 Qemu 模拟 NUMA 架构 -M virt,gic-version3,virtualizationon,typevirt \ -cp…...
【YOLO系列(V5-V12)通用数据集-工程用车检测数据集】
YOLO格式的工程车检测数据集,适用于YOLOv5-v11所有版本,可以用于本科毕设、发paper、做课设等等,有需要的在这里获取: 【YOLO系列(V5-V12)通用数据集-工程用车检测数据集】 【工程车类型检测数据集】共2655…...
卫星智能化健康管理#卫星工程系列
伴随我国航天业飞速发展,积累了大量的卫星试验数据,如何从海量、多源、多模态的卫星试验数据中挖掘分析出内部规律和潜在价值,构建卫星装备系统的全生命周期试验数据知识体系显得尤为迫切。卫星故障传统的诊断方法局限在门限层面,…...
【面试篇】Mysql
1. 请介绍一下 MySQL 常见的存储引擎(如 InnoDB、MyISAM),它们的特点分别是什么?在什么场景下适合使用 InnoDB,什么场景下适合使用 MyISAM? InnoDB: 特点:支持事务,具有…...
Neo4j操作数据库(Cypher语法)
Neo4j数据库操作语法 使用的数据库版本 (终端查询) >neo4j --version 2025.03.0批量上传数据 UNWIND [{name: Alice, age: 30},{name: Bob, age: 25} ] AS person CREATE (p:Person) SET p.name = person.name, p.age = person.age RETURN p;查询结点总数 MATCH (n) RETU…...
当AI开始“思考“:大语言模型的文字认知三部曲
引言:从《黑客帝国》说起 1999年上映的科幻经典《黑客帝国》描绘了一个令人震撼的未来图景——人类生活在一个由人工智能构造的数字矩阵中。当我们观察现代大型语言模型的工作原理时,竟发现与这个虚构世界有着惊人的相似:人们正在用矩阵以及矩…...
[GN] Python3基本数据类型 -- 与C的差异
文章目录 前言Python3的基本数据类型6个标准的数据类型NumbersStringListtupleSetsDictionaries Python运算符逻辑 运算符成员运算符身份运算符 Python3 数字Python3 序列序列切片序列相加序列相乘序列相关内置函数 Python3 列表访问列表的值更新列表删除列表元素拼接列表嵌套列…...
公司论坛数据构建情感标注数据集思考
公司论坛有一个评论区,会有小伙伴在上面进行评论,聊天,大部份都是积极向上的,但是也有小小的一部分消极的言论,“就像白纸上的一个黑点”,和产品对接的大佬如是说。所以想思考做一个情感标注数据集…...
MSF上线到CS工具中 实战方案(可执行方案)
目录 实际案例背景 步骤详解 1. 获取低权限 Meterpreter 会话 1.1 使用 Metasploit 获取会话 2. 提权到 SYSTEM 权限 2.1 使用 getsystem 自动提权 2.2 如果 getsystem 失败:使用令牌冒充 (incognito 模块) 3. 上线到 Cobalt Strike 3.1 生成 Cobalt Strik…...
ffmpeg中格式转换需要注意点总结
某些封装格式(例如MP4/FLV/MKV等)的H.264码流的SPS和PPS信息存储在AVCodeccontext结构体的extradata中。分离某些封装格式(例如MP4/FLV/MKV等)中的H.264的时候,需要首先写入SPS和PPS,否则会导致分离出来的数据没有SPS、PPS而无法播。需要使用ffmpeg中名称…...
IntelliJ IDEA 2020~2024 创建SpringBoot项目编辑报错: 程序包org.springframework.boot不存在
目录 前奏解决结尾 前奏 哈!今天在处理我的SpringBoot项目时,突然遇到了一些让人摸不着头脑的错误提示: java: 程序包org.junit不存在 java: 程序包org.junit.runner不存在 java: 程序包org.springframework.boot.test.context不存在 java:…...
基于DeepSeek、ChatGPT支持下的地质灾害风险评估、易发性分析、信息化建库及灾后重建
前言: 地质灾害是指全球地壳自然地质演化过程中,由于地球内动力、外动力或者人为地质动力作用下导致的自然地质和人类的自然灾害突发事件。在降水、地震等自然诱因的作用下,地质灾害在全球范围内频繁发生。我国不仅常见滑坡灾害,还…...
Websoft9分享:在数字化转型中选择开源软件可能遇到的难题
引言:中小企业数字化转型的必由之路 全球94.57%的企业已采用开源软件(数据来源:OpenLogic 2024报告),开源生态估值达8.8万亿美元。中小企业通过开源软件构建EPR系统、企业官网、数据分析平台等,可节省80%软件采购成本。…...
《在 Ubuntu 22.04 上安装 CUDA 11.8 和 Anaconda,并配置环境变量》
安装 CUDA 11.8 和 Anaconda 并配置环境变量 在本教程中,我们将介绍如何在 Ubuntu 22.04 上安装 CUDA 11.8 和 Anaconda,并配置相应的环境变量。我们还将配置使用 阿里云镜像源 来加速软件包更新。以下是具体步骤。 步骤 1:更新软件源 首先…...
【蓝桥杯】算法笔记3
1. 最长上升子序列(LIS) 1.1. 题目 想象你有一排数字,比如:3, 1, 2, 1, 8, 5, 6 你要从中挑出一些数字,这些数字要满足两个条件: 你挑的数字的顺序要和原来序列中的顺序一致(不能打乱顺序) 你挑的数字要一个比一个大(严格递增) 问:最多能挑出多少个这样的数字? …...
Windows修改hosts文件让向日癸软件联网
Windows修改hosts文件让向日癸软件联网 前言一、查看向日葵软件使用的网址及IP1.清除dns记录2.打开向日葵软件并将dns记录导出txt 二、修改Windows服务器的hosts文件1.winx选择Windows PowerShell(管理员)2.在Windows PowerShell中输入如下内容:3.在hosts文件最后添…...
2021 CCF CSP-S2.括号序列
题目 4091. 括号序列 算法标签: 区间 d p dp dp 思路 区间 d p dp dp添加维表示形态 f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k], 对于每种形态考虑状态如何进行转移, 枚举的时候不能重复, 星号也要定义唯一的解析方式, 算法时间复杂度 O ( n 3 ) O(n ^ 3) O(n3) 代码 #…...
Uni-app 项目 PDF 批注插件库在线版 API 示例教程
本文章介绍 Uni-app 项目中 PDF 批注插件库 ElasticPDF 在线版 API 示例教程,API 包含 ① 导出批注后PDF数据;② 导出纯批注 json 数据;③ 加载旧批注;④ 切换文档;⑤ 切换用户;⑥ 清空批注 等数据处理功能…...
学透Spring Boot — 010. 单元测试和Spring Test
系列文章目录 这是CSDN postnull 博客《学透Spring Boot》系列的一篇,更多文章请移步:Postnull - 学透Spring Boot系列文章 文章目录 系列文章目录前言1. 基本概念UT 单元测试TDD 测试驱动开发UT测试框架Mock框架 3. Spring Test为什么要用Spring Test引…...
TortoiseGit多账号切换配置
前言 之前配置好的都是,TortoiseGit与Gitee之间的提交,突然有需求要在GitHub上提交,于是在参考网上方案和TortoiseGit的帮助手册后,便有了此文。由于GitHub已经配置完成,所以下述以配置Gitee为例。因为之前是单账号使用…...
