前言
本博客的目的是帮助初学者快速入门 Spring MVC,通过简单的示例和详细的说明,介绍 Spring MVC 的基本概念、核心组件以及如何快速构建一个简单的 Web 应用程序。我们将逐步引导您完成从环境配置到请求处理的整个过程,确保您能够掌握 Spring MVC 的关键技能。
SpringMVC简介
SpringMVC是一个基于Spring开发的MVC轻量级框架,pring3.0后发布的组件,SpringMVC和Spring可以无缝整合,使用DispatcherServlet作为前端控制器,且内部提供了处理器映射器、处理器适配器、视图解析器等组件,可以简化JavaBean封装,Json转化、文件上传等操作。

SpringMVC快速入门
导入maven坐标
xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
配置前端控制器DispatcherServlet
创建web.xml文件,内容如下:
xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--配置前端控制器DispatcherServlet-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
< servlet>:定义一个 servlet 的配置。
< servlet-name>:DispatcherServlet 的名称,后续在 servlet-mapping 中引用。
< servlet-class>:指定使用的 servlet 类,这里是 Spring MVC 的核心类 DispatcherServlet,负责处理所有的 HTTP 请求。
< init-param>:用于为 servlet 提供初始化参数。
< param-name>:参数名,这里是 contextConfigLocation,它告诉 DispatcherServlet 加载哪个上下文配置文件。
< param-value>:参数值,这里指定的是 spring-mvc.xml 文件,表示在类路径下查找该文件。此文件通常包含 Spring MVC 的 bean 定义,包括控制器、视图解析器等。
< load-on-startup>:指示 servlet 容器在启动时加载这个 servlet,数字越小,优先级越高。这里设置为 2,意味着这个 servlet 会在其他值更小的 servlet 之前被加载(如果有的话)
< servlet-mapping>:定义哪些 URL 请求由该 servlet 处理。
< url-pattern>:/ 表示所有的请求都会被转发到这个 DispatcherServlet,这使得 Spring MVC 可以处理项目中的所有请求。
java
package com.itheima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class QuickController {
@RequestMapping("/show")
public void show(){
System.out.println("show running.......");
}
}
@Controller:这个注解告诉 Spring 框架,将 QuickController 类标识为一个 Spring MVC 控制器。Spring 会自动检测并注册这个控制器,以便能够处理来自客户端的请求。
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"
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
">
<!--组件扫描-->
<context:component-scan base-package="com.itheima"></context:component-scan>
</beans>
运行代码,访问http://localhost:8080/spring_webmvc_war/show

Controller中访问容器中的Bean
java
@Controller
public class QuickController {
//直接注入service使用
@Autowired
private QuickService quickService;
@RequestMapping("/show")
public void show(){
System.out.println("show running......."+quickService);
}
}
application.xml文件内容如下:
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"
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
">
<!--组件扫描-->
<context:component-scan base-package="com.itheima.service"></context:component-scan>
</beans>
web.xml内容如下:
xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--配置前端控制器DispatcherServlet-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置ContextLoaderListener-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
运行结果如下:

SpringMVC关键组件浅析
上面已经完成的快速入门的操作,也在不知不觉中完成的Spring和SpringMVC的整合,我们只需要按照规则去定义Controller和业务方法就可以。但是在这个过程中,肯定是很多核心功能类参与到其中,这些核心功能类,一般称为组件。当请求到达服务器时,是哪个组件接收的请求,是哪个组件帮我们找到的Controller,是哪个组件帮我们调用的方法,又是哪个组件最终解析的视图?


SpringMVC的默认组件,SpringMVC在前端控制器DispatcherServet加载时,就会进行初始化操作,在进行初始化时,就会加载SpringMVC默认指定的一些组件,这些默认组件配置在DispatcherServlet.properties文件中,该文件存在与spring-webmvc-5.3.7jar包下的 org\springframework\web\servlet\DispatcherServlet.properties
SpringMVC的请求处理
请求映射路径的配置
配置映射路径,映射器处理器才能找到Controller的方法资源,目前主流映射路径配置方式就是@RequestMapping

@RequestMapping注解,主要使用在控制器的方法上,用于标识客户端访问资源路径,常用的属性有value、path、method、headers、params等。当@RequestMapping只有一个访问路径需要指定时,使用value属性、path属
性或省略value和path,当有多个属性时,value和path不能省略
java
@RequestMapping(value = "/show")//使用value属性指定一个访问路径
public String show(){}
@RequestMapping(value = {"/show","/haohao","/abc"})//使用value属性指定多个访问路径
public String show(){}
@RequestMapping(path = "/show")//使用path属性指定一个访问路径
public String show(){}
@RequestMapping(path = {"/show","/haohao","/abc"})//使用path属性指定多个访问路径
public String show(){}
@RequestMapping("/show")//如果只设置访问路径时,value和path可以省略
public String show(){}
@RequestMapping({"/show","/haohao","/abc"})
public String show(){}
当@RequestMapping 需要限定访问方式时,可以通过method属性设置
java
//请求地址是/show,且请求方式必须是POST才能匹配成功
@RequestMapping(value = "/show",method = RequestMethod.POST)
public String show(){}
@RequestMapping 在类上使用,@RequestMapping 、@GetMapping、@PostMapping还可以使用在
Controller类上,使用在类上后,该类所有方法都公用该@RequestMapping设置的属性,访问路径则为类上的映射
地址+方法上的映射地址,例如:
java
@Controller
@RequestMapping("/user")
public class UserController implements ApplicationContextAware, ServletContextAware {
@GetMapping("/show")
public ModelAndView show(HttpServletResponse response) throws IOException,
ModelAndViewDefiningException {
return null;
}
}
请求数据的接收
接收普通请求数据,当客户端提交的数据是普通键值对形式时,直接使用同名形参接收即可
java
name=heima&age=18
java
@GetMapping("/show")
public void Param(String name, int age){
System.outhprintln (name+":"+age);
}
当不同名是我们使用@RequestParam注解
java
@GetMapping("/param1")
public void Param1(@RequestParam("username") String name, String age){
System.out.println(name+": "+age);
}
当请求参数有特殊格式数据,如日期时
java
name=heima&age=18&birthday=2026/01/01
java
@GetMapping("/param")
public void show(String name,int age,Date birthday){
System.out.println(name+":"+age+",生日:"+birthday);
}
Date可以正常接收,因为Spring内置的类型解析器,可以识别的日期格式是 yyyy/MM/dd,但是如果我们提交其他格式,例如:yyyy-MM-dd 时,类型转换会报错,如下:
java
name=heima&age=18&birthday=2026-01-01
解决方案,使用@DateTimeFormat 指定日期格式
java
@GetMapping("/param")
public void param(String name,int age,@DateTimeFormat(pattern = "yyyy-MM-dd") Date
birthday){
System.out.println(name+":"+age+",生日:"+birthday);
}
同时遇到同名的多个值时,可以用数组进行接收 。
java
hobby=play&hobby=run&hobby=swim
java
@GetMapping("/param")
public void Param(String[] hobby){
System.out.println("hobby: "hobby);
}
接收数组或集合数据,客户端传递多个同名参数时,也可以使用单列集合接收,但是需要使用@RequestParam告知框架传递的参数是要同名设置的,不是对象属性设置的
java
@GetMapping("/param")
public void Param(@RequestParam List<String> hobby){
System.out.println("hobby: "hobby);
}
接收数组或集合数据,客户端传递多个不同命名参数时,也可以使用Map<String,Object> 进行接收,同样需要用@RequestParam 进行修饰
java
name=heima&age=18
java
@GetMapping("/param")
public void param(@RequestParam Map<String,Object> params){
params.forEach((key,value)->{
System.out.println(key+"="+value);
});
}
接收实体JavaBean属性数据,单个JavaBean数据:提交的参数名称只要与Java的属性名一致,就可以进行自动封装
java
username=heima&age=18&hobbies=play&hobbies=swim
java
public class User {
private String username;
private Integer age;
private String[] hobbies;
private Date birthday;
private Address address;
省略get和set方法...
}
java
@GetMapping("/show")
public void show(User user){
System.out.println(user);
}
接收Json数据格式数据,Json数据都是以请求体的方式提交的,且不是原始的键值对格式的,所以我们要使用@RequestBody注解整体接收该数据。
json
{
"username": "heima",
"age": 18,
"hobbies": ["swim", "play"],
"birthday": "2026-01-01",
"address": {
"city": "henan",
"area": "sanmenxia"
}
}
java
@PostMapping("/show")
public void show(@RequestBody String body){
System.out.println(body);
}

使用Json工具( jackson )将Json格式的字符串转化为JavaBean进行操作
xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
java
@PostMapping("/show")
public String show(@RequestBody String body) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
User user = objectMapper.readValue(body, User.class);
System.out.println(user);
return "/index.jsp";
}

配置RequestMappingHandlerAdapter,指定消息转换器,就不用手动转换json格式字符串了
xml
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
java
@PostMapping("/show")
public String show(@RequestBody User user) {
System.out.println(user);
return "/index.jsp";
}

总结
随着对 Spring MVC 的深入理解,您可以进一步探索其高级特性,如拦截器、参数转换、国际化等。希望本博客能够为您的学习之旅提供有价值的参考,祝您在 Spring MVC 的开发中取得成功!