目录
一、引言
二、MVC 模式:SpringMVC 的设计基石
2.1 MVC 三大组件
2.2 主流 MVC 框架对比
2.3 MVC 模式的核心优势
三、SpringMVC 框架:是什么?为什么学?
3.1 什么是 SpringMVC?
3.2 为什么要学 SpringMVC?(对比原生 Servlet)
四、SpringMVC 执行流程:从请求到响应的完整链路
4.1 核心组件(无需手动开发,框架提供)
4.2 完整执行流程(图文解析)
五、注解开发 SpringMVC:手把手搭建入门程序
5.1 前置准备
5.2 步骤 1:创建 Maven Web 项目
5.3 步骤 2:添加依赖(pom.xml)
5.4 步骤 3:配置前端控制器(web.xml)
5.5 步骤 4:编写 SpringMVC 核心配置(springmvc.xml)
5.6 步骤 5:开发控制器(Controller)
5.7 步骤 6:开发视图页面
5.8 步骤 7:测试程序
六、入门常见问题解决
6.1 URL 拦截规则:/ vs /* 的区别
6.2 POST 请求参数乱码
七、第一篇总结
一、引言
在 Java Web 开发中,MVC 设计模式是实现代码解耦、提高项目可维护性的核心思想,而SpringMVC作为 Spring 生态体系下的 MVC 框架,凭借其与 Spring 的无缝集成、灵活的配置和简洁的开发风格,早已取代 Struts2 成为主流选择。本文作为系列博客的第一篇,将从 MVC 模式基础入手,带你理解 SpringMVC 的核心定位、执行流程,并手把手教你搭建第一个注解驱动的 SpringMVC 入门程序。
二、MVC 模式:SpringMVC 的设计基石
在学习 SpringMVC 前,必须先掌握 MVC 模式的核心思想 —— 它将应用程序分为三个独立部分,实现 “职责分离”。
2.1 MVC 三大组件
- Model(模型):分为 “业务模型” 和 “数据模型”。业务模型封装业务逻辑(如用户登录校验、订单计算),数据模型封装数据(如 User、Order 实体类),是应用程序的 “数据与逻辑核心”。
- View(视图):负责数据展示,即用户看到的界面(如 JSP、HTML、Freemarker),仅关注 “如何显示数据”,不处理业务逻辑。
- Controller(控制器):作为 “中间枢纽”,接收用户请求,调用 Model 处理业务,再将处理结果传递给 View 展示,实现 View 与 Model 的解耦。
2.2 主流 MVC 框架对比
框架 | 特点 | 适用场景 |
---|---|---|
SpringMVC | 与 Spring 无缝集成、注解驱动、轻量灵活 | 中大型企业级项目(主流) |
Struts2 | 功能全面但配置复杂、性能略低 | 传统项目(逐渐被淘汰) |
JFinal | 轻量级、API 简洁、开发效率高 | 小型项目或快速原型开发 |
2.3 MVC 模式的核心优势
- 解耦:View 与 Model 分离,同一业务逻辑可对应多个视图(如 PC 端、移动端页面)。
- 可维护性:各组件职责单一,修改视图不影响业务逻辑,修改业务不影响视图。
- 可扩展性:新增功能只需新增 Controller 或 Model,无需改动现有视图。
三、SpringMVC 框架:是什么?为什么学?
3.1 什么是 SpringMVC?
- 定位:SpringMVC 是 Spring Framework 的子框架,本质是对 Servlet 的封装,解决了原生 Servlet 的痛点(如请求映射繁琐、参数接收复杂)。
- 核心特性:
- 注解驱动:通过
@Controller
、@RequestMapping
等注解,让普通 POJO 成为控制器,无需实现接口。 - 松散耦合:支持可插拔组件(如视图解析器、参数绑定组件),扩展性强。
- 无缝集成 Spring:可直接使用 Spring 的 IOC、AOP 等功能(如依赖注入 Service 层)。
- 易测试:支持 Web 层单元测试,无需启动服务器即可测试控制器。
- 注解驱动:通过
3.2 为什么要学 SpringMVC?(对比原生 Servlet)
原生 Servlet 开发存在三大痛点,而 SpringMVC 完美解决:
- 请求映射繁琐:100 个请求需写 100 个 Servlet,即使合并 Servlet 也需手动判断请求路径,耦合度高;SpringMVC 通过
@RequestMapping
一键绑定 URL。 - 参数接收复杂:需手动调用
request.getParameter("username")
获取参数,还需手动类型转换(如 String 转 Integer);SpringMVC 自动完成参数绑定与类型转换。 - 解耦不足:Servlet 与业务逻辑代码耦合,难以维护;SpringMVC 通过 Controller 调用 Service,层次清晰。
四、SpringMVC 执行流程:从请求到响应的完整链路
SpringMVC 的执行流程依赖其核心组件的协作,理解流程是掌握框架的关键。
框架处理流程图:
4.1 核心组件(无需手动开发,框架提供)
- 前端控制器(DispatcherServlet):全局入口,接收所有请求,转发给其他组件处理,降低组件耦合。
- 处理器映射器(HandlerMapping):根据请求 URL 查找对应的 “处理器(Controller 方法)”,返回 HandlerExecutionChain(包含处理器和拦截器)。
- 处理器适配器(HandlerAdapter):适配不同类型的处理器(如注解式、接口式),调用处理器的业务方法。
- 处理器(Handler/Controller):开发者编写的 Controller 类,封装业务逻辑,返回 ModelAndView(模型数据 + 逻辑视图名)。
- 视图解析器(ViewResolver):将 “逻辑视图名”(如 "ok.jsp")解析为 “物理视图”(如
/WEB-INF/jsp/ok.jsp
)。 - 视图(View):开发者编写的 JSP/HTML,渲染 Model 中的数据并响应给用户。
4.2 完整执行流程(图文解析)
- 用户发送请求(如
http://localhost:8080/reg.do
),请求被DispatcherServlet拦截。 - DispatcherServlet 调用HandlerMapping,根据 URL 找到对应的 Controller 方法(如
UserController
的show()
方法)。 - DispatcherServlet 调用HandlerAdapter,适配并调用找到的 Controller 方法。
- Controller 方法执行业务逻辑,返回ModelAndView(如模型数据
uname=张三
,逻辑视图名ok.jsp
)。 - DispatcherServlet 调用ViewResolver,将逻辑视图名
ok.jsp
解析为物理视图路径(如/ok.jsp
)。 - ViewResolver 返回 View 对象,DispatcherServlet 调用 View 的
render()
方法,渲染 Model 数据到视图。 - 渲染完成后,DispatcherServlet 将响应结果返回给用户,流程结束。
五、注解开发 SpringMVC:手把手搭建入门程序
本节将基于 IDEA+Maven+Tomcat,实现一个 “用户注册” 功能,涵盖环境搭建、配置编写、控制器开发全流程。
5.1 前置准备
- IDEA 版本:需旗舰版(Community 版不支持 Web 开发),下载地址:JetBrains IDEA。
- Tomcat 配置:
- 解压 Tomcat 到本地(如
D:\Tomcat8.5
)。 - IDEA 中依次点击:
Run → Edit Configurations → Templates → Tomcat Server → Local → Configure
,选择 Tomcat 解压路径。 - 新建 Tomcat 配置:点击
+ → Tomcat Server → Local
,设置 Name(如 Tomcat8.5),在Deployment
中添加项目的war exploded
包。
- 解压 Tomcat 到本地(如
5.2 步骤 1:创建 Maven Web 项目
- 新建项目:
New Project → Maven → 勾选Create from archetype → 选择org.apache.maven.archetypes:maven-archetype-webapp
。 - 填写项目信息:GroupId(如
com.jr
)、ArtifactId(如springmvc-demo
)、Version(如1.0-SNAPSHOT
)。 - 补全目录:项目创建后,手动在
src/main
下添加java
(标记为 Sources Root)和resources
(标记为 Resources Root)目录。
5.3 步骤 2:添加依赖(pom.xml)
需引入 Spring 核心包、SpringMVC 包、Servlet/JSP 包、JSTL 包,完整依赖如下:
<dependencies><!-- JUnit测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><!-- Spring核心包 --><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>4.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>4.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>4.1.6.RELEASE</version></dependency><!-- SpringMVC包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>4.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>4.1.6.RELEASE</version></dependency><!-- Servlet/JSP依赖 --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.3</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.2</version><scope>provided</scope></dependency><!-- JSTL标签库 --><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency>
</dependencies>
5.4 步骤 3:配置前端控制器(web.xml)
前端控制器是 SpringMVC 的入口,需在WEB-INF/web.xml
中配置,核心作用是拦截请求并转发:
<web-app version="2.5"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><!-- 欢迎页 --><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><!-- 配置SpringMVC前端控制器 --><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 指定SpringMVC配置文件路径(默认在WEB-INF/[servlet-name]-servlet.xml) --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><!-- 启动Tomcat时自动加载Servlet --><load-on-startup>1</load-on-startup></servlet><!-- 拦截规则:/ 表示拦截所有请求(除JSP外) --><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 配置乱码过滤器(解决POST请求参数乱码) --><filter><filter-name>charsetFilter</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>charsetFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
</web-app>
5.5 步骤 4:编写 SpringMVC 核心配置(springmvc.xml)
在src/main/resources
下创建springmvc.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"><!-- 1. 扫描Controller注解(指定包路径) --><context:component-scan base-package="com.jr.controller"/><!-- 2. 开启注解驱动:自动加载处理器映射器、处理器适配器 --><mvc:annotation-driven/><!-- 3. 静态资源放行(如JS、CSS、图片,避免被DispatcherServlet拦截) --><mvc:resources location="/js/" mapping="/js/**"/><mvc:resources location="/images/" mapping="/images/**"/>
</beans>
5.6 步骤 5:开发控制器(Controller)
在src/main/java/com/jr/controller
下创建UserController
,使用@Controller
标记为控制器,@RequestMapping
绑定请求路径:
package com.jr.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;@Controller // 标记此类为SpringMVC控制器
public class UserController {// 绑定请求路径:http://localhost:8080/reg.do@RequestMapping("reg.do")public ModelAndView register(HttpServletRequest request) {// 1. 创建ModelAndView对象(封装模型数据和视图名)ModelAndView mv = new ModelAndView();// 2. 接收请求参数(此处用原生Servlet API,后续会优化)String username = request.getParameter("username");String password = request.getParameter("password");// 3. 封装模型数据(存入request作用域,供视图使用)mv.addObject("uname", username); // 等价于request.setAttribute("uname", username)// 4. 指定逻辑视图名(视图解析器会解析为物理路径)mv.setViewName("ok.jsp");return mv;}
}
5.7 步骤 6:开发视图页面
注册页面(index.jsp):在webapp
下创建,提供用户输入表单:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>用户注册</title>
</head>
<body>
<form action="reg.do" method="post">用户名:<input type="text" name="username"><br>密码:<input type="password" name="password"><br><input type="submit" value="提交注册">
</form>
</body>
</html>
成功页面(ok.jsp):在webapp
下创建,展示注册成功信息:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>注册成功</title>
</head>
<body>
<h3>注册成功!欢迎您,${uname}!</h3> <!-- EL表达式获取模型数据 -->
</body>
</html>
5.8 步骤 7:测试程序
- 启动 Tomcat,访问
http://localhost:8080/springmvc-demo/
(项目上下文路径根据配置调整)。 - 输入用户名和密码,点击 “提交注册”,页面跳转至
ok.jsp
并显示欢迎信息,说明程序运行成功。
六、入门常见问题解决
6.1 URL 拦截规则:/
vs /*
的区别
/
:拦截所有请求(除 JSP 外),是 SpringMVC 推荐配置。JSP 由 Tomcat 的 JspServlet 处理,不会被拦截,可正常渲染。/*
:拦截所有请求(包括 JSP),会导致 JSP 被 DispatcherServlet 当作控制器处理,找不到对应映射而报 404 错误,禁止使用。
6.2 POST 请求参数乱码
如步骤 3 中配置的CharacterEncodingFilter
,通过encoding=UTF-8
强制设置请求和响应的字符编码,解决 POST 乱码问题(GET 乱码需修改 Tomcat 的server.xml
,添加URIEncoding="UTF-8"
)。
七、第一篇总结
本文从 MVC 模式基础出发,讲解了 SpringMVC 的核心定位、执行流程,并通过 “用户注册” 案例完整演示了注解开发的入门流程。你已掌握:
- MVC 模式的三大组件与职责分离思想;
- SpringMVC 的核心特性与执行流程;
- 基于 Maven+IDEA 的 SpringMVC 环境搭建;
- 控制器开发与请求映射、视图跳转的基本用法。
下一篇博客将深入 SpringMVC 的核心功能,讲解请求映射、返回值类型与参数绑定,带你实现更灵活的业务逻辑开发。