在现代 Web 开发中,高效、稳定、可扩展的框架至关重要。Spring WebMvc 作为 Spring Framework 的核心模块之一,为开发人员提供了强大的 MVC 体系支持,使得 Web 应用的构建更加便捷和规范。无论是传统的 JSP 视图渲染,还是基于 RESTful 的 API 设计,Spring WebMvc 都能提供完善的解决方案。
本篇文章将深入解析 Spring WebMvc 模块的核心概念、依赖关系、组件架构及其应用场景,并通过一个完整的示例,帮助读者理解如何使用 Spring WebMvc 构建高效的 Web 应用。希望通过本篇内容,让你能更加熟练地掌握 Spring MVC 及其实践应用。
Spring WebMvc 是 Spring Framework 的核心模块之一,专门用于构建基于 MVC(Model-View-Controller)设计模式的 Web 应用程序。作为 Spring 对 Servlet API 的封装实现,它通过清晰的职责划分和高效的请求处理机制,简化了传统同步 Web 应用及 REST API 的开发流程。
该模块的核心特性包括:
@Controller
、@RestController
、@RequestMapping
等注解实现请求路由与处理。HandlerInterceptor
实现预处理和后处理逻辑。@ControllerAdvice
)和自定义错误页面。@RequestBody
、@ResponseBody
实现 JSON/XML 数据交互。Spring WebMvc 遵循 “约定优于配置” 原则,既能通过 XML 配置实现传统开发模式,也可借助 Spring Boot 实现零配置快速启动,广泛应用于企业级 Web 应用开发。
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
(安全控制)等扩展模块。
核心作用:
请求处理流水线基于 DispatcherServlet
的前端控制器模式,将 HTTP 请求分发给对应的 Controller,处理流程包括:
HandlerMapping
)DataBinder
)Controller
)ViewResolver
)HandlerExceptionResolver
)分层架构支持: Model:通过 POJO 或 Model
对象封装业务数据。View:解耦视图技术,支持模板引擎或静态页面。Controller:集中处理用户请求,协调业务逻辑与数据呈现。
扩展性与兼容性 :可集成第三方组件(如 Spring Security、Swagger)。兼容 Servlet 3.0+ 规范,支持异步请求处理(DeferredResult
/Callable
)。
Spring WebMvc 下述组件的协同工作,Spring WebMvc 实现了高度可定制化的 Web 开发框架,兼顾灵活性与开发效率:
DispatcherServlet
:中央调度器,协调各组件完成请求处理生命周期。HandlerMapping
:根据 URL 匹配对应的 Controller 方法。HandlerAdapter
:适配不同处理器类型(如 @Controller
、Servlet)。ViewResolver
:将逻辑视图名解析为具体视图实现(如 JSP 页面)。MultipartResolver
:处理文件上传请求。LocaleResolver
:支持国际化与本地化。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 接收。MVC 的优点:
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
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">
<servlet>
<servlet-name>dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>/WEB-INF/spring-mvc-config.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
src/main/webapp/WEB-INF/spring-mvc-config.xml
<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
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<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>
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; }
}
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, "张三", "[email protected]"));
users.add(new User(2L, "李四", "[email protected]"));
}
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);
}
}
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;
}
@GetMapping
public 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";
}
@PostMapping
public String addUser(@ModelAttribute User user) {
userService.addUser(user);
return "redirect:/users";
}
}
src/main/webapp/WEB-INF/views/users.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
用户列表
用户列表
src/main/webapp/WEB-INF/views/user.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
用户详情
用户详情
姓名: ${user.name}
邮箱: ${user.email}
返回列表
使用 Tomcat 部署,或者在 IDE 中运行:
mvn tomcat7:run
然后访问:
http://localhost:8080/users
获取所有用户http://localhost:8080/users/1
获取特定用户信息Spring WebMvc 模块是构建现代 Web 应用的重要基石,它提供了清晰的架构分层,使开发者能够专注于业务逻辑,而无需过多关注底层的请求处理细节。通过 DispatcherServlet
这一核心组件,Spring WebMvc 实现了从请求到视图渲染的完整流程,并结合 Spring 的强大生态系统,提供了丰富的扩展能力。
本篇文章从基础概念到实际应用,系统地介绍了 Spring WebMvc 的核心功能,希望能为你的 Web 开发提供实用的指导。在实际开发中,建议结合 Spring Boot 进行整合,以实现更快速的配置和开发。如果你对 Web 开发有更深入的需求,可以进一步探索 Spring Security、Spring Cloud 等相关技术,不断提升自身的技术能力。
愿你的开发之旅更加高效顺畅!