一、Spring MVC概述
1、为什么要使用SpringMVC?
在传统的Servlet开发中,我们通常需要手动处理请求参数、业务逻辑和视图跳转,代码冗余且维护困难。SpringMVC正是为了解决这些问题而设计的。
传统Servlet开发示例:
java
@WebServlet("/addUser")
public class AddUserServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
// 需要手动接收每个参数
String username = req.getParameter("username");
String password = req.getParameter("password");
// ...更多参数处理
}
}
Servlet的主要缺陷:
-
一个Servlet实例只能处理一个请求
-
参数接收过程繁琐,需要手动转换类型
-
代码重复度高,可维护性差
2、 MVC设计模式
MVC(Model-View-Controller)是一种将应用程序分为三个核心组件的设计模式:
-
M(Model,模型层):处理业务逻辑和数据
-
数据承载Bean:如User、Student等实体类
-
业务处理Bean:如Service、Dao等业务组件
-
-
V(View,视图层):负责用户界面展示,如JSP、HTML页面
-
C(Controller,控制层):接收用户请求并调用模型处理,如Servlet
MVC工作流程:
-
用户通过视图层发送请求
-
控制器接收请求并调用相应的模型处理
-
模型处理业务逻辑后返回结果给控制器
-
控制器根据结果选择合适的视图渲染数据
-
最终响应给浏览器

MVC与三层架构关系:
-
三层架构:基于业务逻辑分层(表现层、业务层、数据层)
-
MVC:基于页面功能分层,专注于表现层的实现
-
两者是协作关系而非上下级关系
3、 Spring MVC介绍
Spring MVC是Spring Framework的一个模块,是基于MVC设计模式的轻量级Web开发框架。它通过注解驱动的方式简化了Web开发,目前已成为Java EE项目表现层开发的首选方案。
二、 SpringMVC环境搭建
1、 创建工程
首先创建一个Maven项目,并添加Web框架支持。以下是关键步骤:
<img src="assets/image-20211012185038920.png" alt="创建Maven项目" style="zoom:67%;" />
注意事项:
-
先添加框架支持,再设置打包方式
-
将web目录拖拽到main目录下,并重命名为webapp
2、核心配置文件
2.1、 pom.xml依赖配置
XML
<dependencies>
<!-- Spring上下文 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- SpringMVC核心 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
2.2、springmvc.xml配置
XML
<!-- 组件扫描 -->
<context:component-scan base-package="com.hg"></context:component-scan>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 开启注解支持 -->
<mvc:annotation-driven></mvc:annotation-driven>
2.3、web.xml配置
XML
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置SpringMVC配置文件位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 启动时立即创建 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3、 SpringMVC核心组件
3.1、 DispatcherServlet(前端控制器)
整个流程的控制中心,接收所有请求并调用其他组件处理。
3.2、 HandlerMapping(处理器映射器)
根据请求URL找到对应的处理器(Handler)。
3.3、 Handler(处理器)
开发者编写的业务控制器,处理具体业务逻辑。
3.4、 HandlerAdapter(处理器适配器)
执行处理器,适配不同类型的处理器实现。

适配器类型:
-
AnnotationMethodHandlerAdapter:适配注解类处理器(@Controller)
-
HttpRequestHandlerAdapter:适配静态资源处理器
-
SimpleControllerHandlerAdapter:适配实现Controller接口的处理器
-
SimpleServletHandlerAdapter:适配实现Servlet接口的处理器
3.5、 View Resolver(视图解析器)
将逻辑视图名解析为物理视图地址。
3.6、View(视图)
将模型数据渲染到视图页面。
4、 SpringMVC执行流程

详细执行步骤:
-
用户请求到达DispatcherServlet
-
DispatcherServlet调用HandlerMapping查找Handler
-
HandlerMapping返回HandlerExecutionChain
-
DispatcherServlet调用HandlerAdapter执行Handler
-
Handler处理请求,返回ModelAndView
-
HandlerAdapter返回ModelAndView给DispatcherServlet
-
DispatcherServlet调用ViewResolver解析视图
-
ViewResolver返回View对象
-
DispatcherServlet渲染视图并响应
三、 @RequestMapping注解详解
1、 基本用法
用于建立请求URL和处理方法之间的映射关系。
出现在类上:
java
@Controller
@RequestMapping("/account") // 一级访问目录
public class AccountController {
@RequestMapping("/add") // 二级访问目录
public String add() {
return "success";
}
}
访问URL:/account/add
属性说明:
-
value/path:指定请求URL -
method:指定请求方式(GET、POST等)
2、 窄化路径示例
java
@Controller
@RequestMapping("/account")
public class AccountController {
@RequestMapping("/findAccount")
public ModelAndView findAccount() {
ModelAndView mv = new ModelAndView();
mv.addObject("msg", "欢迎你 springmvc");
mv.setViewName("success");
return mv;
}
}
JSP页面调用:
html
<a href="/account/findAccount">窄化路径</a>
3、 method属性限制请求方式
java
@RequestMapping(value = "/findAccount1", method = RequestMethod.POST)
public ModelAndView findAccount1() {
// 只能通过POST方式访问
return new ModelAndView("success");
}
四、 Controller方法返回值
1、 返回ModelAndView
最完整的返回方式,包含模型数据和视图信息:
java
@RequestMapping("/hello")
public ModelAndView hello() {
ModelAndView mv = new ModelAndView();
mv.addObject("hello", "欢迎你 springmvc");
mv.setViewName("success");
return mv;
}
2、返回字符串
2.1、返回逻辑视图名
java
@RequestMapping("/findAccount2")
public String findAccount2(Model model) {
model.addAttribute("msg", "欢迎你 springmvc");
return "success"; // 返回视图名称
}
2.2、Redirect重定向
java
@RequestMapping("/findAccount3")
public String findAccount3() {
return "redirect:/account/findAccount4";
}
特点:浏览器地址栏改变,参数不传递
2.3、 Forward转发
java
@RequestMapping("/findAccount3")
public String findAccount3() {
return "forward:/account/findAccount4";
}
特点:浏览器地址栏不变,参数可传递
五、 参数接收
1、 基本数据类型参数
java
@RequestMapping("/findAccount5")
public String findAccount5(String username, Model model) {
model.addAttribute("msg", username);
return "success";
}
@RequestMapping("/findAccount6")
public String findAccount6(String username, Integer age, Model model) {
model.addAttribute("msg", username + " " + age);
return "success";
}
JSP调用:
html
<a href="/account/findAccount5?username=eric">单个参数</a>
<a href="/account/findAccount6?username=eric&age=22">多个参数</a>
2、 POJO类型参数绑定
当表单参数较多时,可以使用POJO对象统一接收。
POJO类定义:
java
public class Account implements Serializable {
private Integer id;
private String name;
private Float money;
private Address address; // 嵌套对象
// getter/setter省略
}
public class Address implements Serializable {
private String provinceName;
private String cityName;
// getter/setter省略
}
Controller方法:
java
@RequestMapping("/saveAccount")
public String saveAccount(Account account, Model model) {
model.addAttribute("msg", account);
return "success";
}
JSP表单:
html
<form action="account/saveAccount" method="post">
账户名称:<input type="text" name="name"><br/>
账户金额:<input type="text" name="money"><br/>
账户省份:<input type="text" name="address.provinceName"><br/>
账户城市:<input type="text" name="address.cityName"><br/>
<input type="submit" value="保存">
</form>
参数绑定规则:
-
基本类型和String类型:参数名与属性名一致即可自动绑定
-
POJO类型:参数名与属性名一致,支持级联属性(如address.provinceName)
-
数组/集合类型:需要特殊处理