1. Spring MVC 整体概述
Spring MVC 是 Spring 框架里专门用于构建 Web 应用程序的模块,它基于经典的 MVC(Model - View - Controller)设计模式。该模式将应用程序划分为三个主要部分,使代码的职责更加清晰,从而提高了开发效率、可维护性和可扩展性。在企业级 Web 开发中,Spring MVC 凭借其强大的功能和灵活性,成为了开发者的热门选择。
2. MVC 设计模式各部分在 Spring MVC 中的详细剖析
2.1 模型(Model)
- 概念与作用:模型在 Spring MVC 中主要负责处理数据和业务逻辑。它是应用程序的核心数据层,代表了业务实体和与之相关的操作。模型可以从各种数据源(如数据库、文件系统、Web 服务等)获取数据,并对数据进行加工、转换和验证等操作,最终将处理好的数据提供给视图进行展示。
- 类型与示例:
- 实体类模型:通常是简单的 JavaBean,用于封装数据。比如在一个博客系统中,
Article类可以作为实体类模型,包含文章的标题、内容、作者、发布时间等属性。
- 实体类模型:通常是简单的 JavaBean,用于封装数据。比如在一个博客系统中,
public class Article {
private int id;
private String title;
private String content;
private String author;
private Date publishDate;
// 构造函数、Getter 和 Setter 方法
public Article(int id, String title, String content, String author, Date publishDate) {
this.id = id;
this.title = title;
this.content = content;
this.author = author;
this.publishDate = publishDate;
}
// Getter 和 Setter 方法省略
}
- 服务类模型:负责处理具体的业务逻辑。例如
ArticleService类,它可能包含查询文章列表、保存文章、更新文章等方法。
import java.util.ArrayList;
import java.util.List;
public class ArticleService {
public List<Article> getArticleList() {
List<Article> articleList = new ArrayList<>();
// 模拟从数据库获取文章列表
articleList.add(new Article(1, "第一篇文章", "文章内容...", "作者 A", new java.util.Date()));
articleList.add(new Article(2, "第二篇文章", "文章内容...", "作者 B", new java.util.Date()));
return articleList;
}
public void saveArticle(Article article) {
// 实现保存文章到数据库的逻辑
}
}
2.2 视图(View)
- 概念与作用:视图是用户界面的呈现部分,它负责将模型中的数据以直观、友好的方式展示给用户。视图不处理业务逻辑,只专注于数据的展示和格式化。
- 常见视图技术及示例:
- JSP(JavaServer Pages):是一种传统的 Java Web 视图技术,它允许在 HTML 页面中嵌入 Java 代码。例如,下面是一个简单的 JSP 页面用于展示文章列表。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>文章列表</title>
</head>
<body>
<h1>文章列表</h1>
<ul>
<% java.util.List<Article> articleList = (java.util.List<Article>) request.getAttribute("articleList"); %>
<% for (Article article : articleList) { %>
<li>
<a href="articleDetail?id=<%= article.getId() %>"><%= article.getTitle() %></a>
<p>作者:<%= article.getAuthor() %></p>
</li>
<% } %>
</ul>
</body>
</html>
- Thymeleaf:是一个现代的服务器端 Java 模板引擎,它可以在 HTML 页面中使用自然的模板语法。以下是使用 Thymeleaf 展示文章列表的示例。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>文章列表</title>
</head>
<body>
<h1>文章列表</h1>
<ul>
<li th:each="article : ${articleList}">
<a th:href="@{/articleDetail(id=${article.id})}" th:text="${article.title}"></a>
<p th:text="${'作者:' + article.author}"></p>
</li>
</ul>
</body>
</html>
- Freemarker:也是一种常用的模板引擎,它使用简单的文本模板和数据模型来生成输出。以下是一个简单的 Freemarker 模板示例。
<!DOCTYPE html>
<html>
<head>
<title>文章列表</title>
</head>
<body>
<h1>文章列表</h1>
<ul>
<#list articleList as article>
<li>
<a href="/articleDetail?id=${article.id}">${article.title}</a>
<p>作者:${article.author}</p>
</li>
</#list>
</ul>
</body>
</html>
2.3 控制器(Controller)
- 概念与作用:控制器是 Spring MVC 的核心协调者,它接收用户的请求,根据请求的信息调用相应的模型进行数据处理,然后选择合适的视图将处理结果展示给用户。控制器起到了连接模型和视图的桥梁作用。
- 控制器的实现与示例:在 Spring MVC 中,控制器通常是一个 Java 类,使用
@Controller注解进行标识,方法使用@RequestMapping注解来映射请求的 URL。
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
public class ArticleController {
private ArticleService articleService = new ArticleService();
@RequestMapping("/articleList")
public String getArticleList(Model model) {
List<Article> articleList = articleService.getArticleList();
model.addAttribute("articleList", articleList);
return "articleList"; // 返回视图名称
}
@RequestMapping("/articleDetail")
public String getArticleDetail(int id, Model model) {
// 根据文章 ID 获取文章详情
Article article = articleService.getArticleById(id);
model.addAttribute("article", article);
return "articleDetail";
}
}
3. Spring MVC 的工作流程详解
3.1 用户请求
用户通过浏览器在地址栏输入 URL 或者点击页面上的链接、提交表单等操作,向服务器发送 HTTP 请求。请求中包含了请求的 URL、请求方法(如 GET、POST 等)、请求参数等信息。
3.2 前端控制器(DispatcherServlet)接收请求
- 初始化与配置:
DispatcherServlet是 Spring MVC 的核心组件,它是一个 Servlet,在 Web 应用启动时被初始化。通常在web.xml或者使用 Java 配置的方式进行配置。以下是在web.xml中的配置示例。
<servlet>
<servlet-name>dispatcherServlet</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>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
- 接收与分发:
DispatcherServlet接收所有的用户请求,它就像一个中央调度器,将请求分发给后续的组件进行处理。
3.3 处理器映射(Handler Mapping)
- 作用与原理:处理器映射的作用是根据请求的 URL 找到对应的控制器方法。它通过配置规则将 URL 与控制器方法进行映射。常见的处理器映射有
RequestMappingHandlerMapping(基于注解的映射)和SimpleUrlHandlerMapping(基于 XML 配置的映射)。 - 示例(基于注解的映射):在使用
@RequestMapping注解的控制器中,RequestMappingHandlerMapping会根据注解中的 URL 信息进行映射。例如,在ArticleController中,@RequestMapping("/articleList")注解将/articleList这个 URL 映射到getArticleList方法。
3.4 调用控制器方法
- 参数绑定与调用:
DispatcherServlet找到对应的控制器方法后,会根据请求的参数信息进行参数绑定。例如,如果请求中包含id参数,DispatcherServlet会将该参数值传递给控制器方法中对应的id参数。然后调用控制器方法进行业务处理。 - 返回结果处理:控制器方法处理完请求后,会返回一个逻辑视图名称和一个模型对象(可选)。逻辑视图名称用于指定要使用的视图,模型对象包含了要传递给视图的数据。
3.5 返回模型和视图信息
控制器方法将处理结果封装在模型中,并返回一个逻辑视图名称。例如,在 ArticleController 的 getArticleList 方法中,将文章列表数据添加到模型中,并返回 articleList 这个逻辑视图名称。
3.6 视图解析器(View Resolver)
- 作用与类型:视图解析器的作用是根据逻辑视图名称找到对应的实际视图文件。常见的视图解析器有
InternalResourceViewResolver(用于解析 JSP 视图)、ThymeleafViewResolver(用于解析 Thymeleaf 视图)、FreeMarkerViewResolver(用于解析 Freemarker 视图)等。 - 示例(InternalResourceViewResolver):以下是在 Spring 配置文件中配置
InternalResourceViewResolver的示例。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
在这个配置中,逻辑视图名称 articleList 会被解析为 /WEB-INF/views/articleList.jsp。
3.7 渲染视图
- 数据传递与渲染:
DispatcherServlet将模型中的数据传递给视图,视图根据自身的模板语法将数据渲染成 HTML 页面。例如,JSP 页面会将模型中的数据通过<%= %>等标签进行展示,Thymeleaf 页面会使用th:前缀的属性进行数据绑定和展示。 - 返回响应:渲染完成后,将生成的 HTML 页面作为 HTTP 响应返回给用户的浏览器,用户在浏览器中就可以看到最终的页面内容。
4. Spring MVC 的核心组件深入分析
4.1 DispatcherServlet
- 核心地位与功能:
DispatcherServlet是 Spring MVC 的核心,它负责接收所有的用户请求,并协调各个组件之间的工作。它就像一个指挥中心,控制着整个请求处理流程,确保请求能够正确地被分发、处理和响应。 - 生命周期管理:在 Web 应用启动时,
DispatcherServlet会被初始化,加载 Spring 配置文件,创建并管理 Spring 容器。在应用关闭时,DispatcherServlet会进行相应的销毁操作。
4.2 HandlerMapping
- 多种实现方式:除了前面提到的
RequestMappingHandlerMapping和SimpleUrlHandlerMapping,还有BeanNameUrlHandlerMapping等。不同的处理器映射适用于不同的场景,开发者可以根据项目需求进行选择。 - 配置与使用:在 Spring 配置文件中可以配置处理器映射。例如,使用基于注解的映射时,只需要确保控制器类和方法使用了正确的注解,Spring 会自动进行映射。
4.3 HandlerAdapter
- 适配不同控制器方法:由于控制器方法的参数和返回值类型可能不同,
HandlerAdapter负责将请求的参数绑定到控制器方法的参数上,并处理控制器方法的返回值。它提供了统一的调用接口,使得DispatcherServlet可以以一致的方式调用不同类型的控制器方法。 - 常见实现类:
RequestMappingHandlerAdapter是常用的实现类,它支持基于注解的控制器方法调用。
4.4 ViewResolver
- 视图解析策略:不同的视图解析器有不同的视图解析策略。例如,
InternalResourceViewResolver是基于 JSP 页面的物理路径进行解析,ThymeleafViewResolver会根据 Thymeleaf 模板的配置信息进行解析。 - 配置与扩展:可以在 Spring 配置文件中配置视图解析器的属性,如前缀、后缀等。同时,开发者也可以自定义视图解析器来满足特殊的需求。
4.5 控制器(Controller)
- 注解驱动开发:使用
@Controller注解可以将一个普通的 Java 类标识为控制器类。@RequestMapping注解可以精确地映射请求的 URL 和控制器方法。此外,还有@GetMapping、@PostMapping等更细化的注解,用于指定请求方法。 - 数据绑定与验证:控制器方法可以使用
@RequestParam、@PathVariable等注解进行参数绑定,还可以使用 Spring 的数据验证框架(如@Valid注解)对请求参数进行验证。
4.6 视图(View)
- 视图类型与选择:不同的视图类型适用于不同的场景。JSP 适合传统的 Java Web 开发,Thymeleaf 具有良好的模板语法和自然的 HTML 集成性,Freemarker 则以其简单的语法和高性能著称。开发者可以根据项目的需求和团队的技术栈选择合适的视图类型。
- 视图渲染与国际化:视图在渲染时可以处理国际化的需求,通过 Spring 的国际化支持,可以根据用户的语言环境展示不同语言的页面内容。
5. Spring MVC 的优点总结
5.1 灵活性
- 视图技术选择:支持多种视图技术,开发者可以根据项目的需求和团队的技术能力选择合适的视图技术,如 JSP、Thymeleaf、Freemarker 等。
- 配置方式多样:支持 XML 配置、Java 配置和注解配置。XML 配置适合大型项目的全局配置,Java 配置适合使用 Java 代码进行配置的场景,注解配置则简洁方便,适合快速开发。
5.2 可维护性
- 职责分离:采用 MVC 设计模式,将业务逻辑、数据处理和页面展示分离,使得代码的职责更加清晰。当业务需求发生变化时,只需要修改相应的模型、控制器或视图,而不会影响其他部分的代码。
- 代码结构清晰:Spring MVC 的组件化设计使得代码结构更加清晰,易于理解和维护。每个组件都有明确的职责,降低了代码的耦合度。
5.3 可测试性
- 单元测试支持:控制器方法可以独立进行单元测试,通过模拟请求和响应对象,可以方便地测试控制器方法的逻辑。例如,使用 JUnit 和 Mockito 等测试框架可以对控制器方法进行单元测试。
- 集成测试框架:Spring MVC 提供了测试框架,如
MockMvc,可以对整个 Web 应用进行集成测试。MockMvc可以模拟 HTTP 请求,测试请求的处理流程和视图渲染结果。
5.4 与 Spring 框架集成
- 无缝集成其他模块:Spring MVC 是 Spring 框架的一部分,可以方便地与 Spring 的其他模块(如 Spring Core、Spring AOP、Spring Data 等)集成。例如,可以使用 Spring 的 IoC 和 AOP 特性来管理控制器和服务类的依赖关系,以及实现横切关注点的处理。还可以与 Spring Data 集成,方便地进行数据库操作。

2639

被折叠的 条评论
为什么被折叠?



