跳到主要内容
Spring Boot 创建第一个项目与 Spring Web MVC 入门 | 极客日志
Java java
Spring Boot 创建第一个项目与 Spring Web MVC 入门 Spring Web MVC 是基于 Servlet API 构建的 Web 框架,实现了 MVC 设计模式。内容涵盖 Spring Boot 集成 Spring Web 的方法,RequestMapping 路由映射配置,以及请求参数接收的各种形式,如基本类型、包装类、对象、数组和集合。重点解析了 @RequestParam 注解在参数绑定与重命名中的作用,阐明前后端交互机制及常见参数处理方案。
邪神洛基 发布于 2026/3/15 更新于 2026/4/24 3 浏览1.什么是 Spring Web MVC?
官方对于 Spring MVC 的描述是这样的:
Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, 'Spring Web MVC', comes from the name of its source module (spring-webmvc)
引用来自:Spring 官方
Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从一开始就包含在 Spring 框架中。它的正式名称'Spring Web MVC'来自其源模块的名称 (Spring-webmvc),但它通常被称为"Spring MVC"。
什么是 Servlet 呢?
Servlet 是一种实现动态页面的技术。准确来讲 Servlet 是一套 Java Web 开发的规范,或者说是一套 Java Web 开发的技术标准。只有规范并不能做任何事情,必须要有的人去实现它。所谓实现 Servlet 规范,就是真正编写代码去实现 Servlet 规范提到的各种功能,包括类、方法、属性等。
Servlet 规范是开放的,除了 Sun 公司,其它公司也可以实现 Servlet 规范,目前常见的实现了 Servlet 规范的产品包括 Tomcat、Weblogic、Jetty、Jboss、WebSphere 等,它们都被称为"Servlet 容器'。Servlet 容器用来管理程序员编写的 Servlet 类。
从上述定义我们可以得出一个信息:Spring Web MVC 是一个 Web 框架。下面咱们简称之为:Spring MVC
然而要真正的理解什么是 Spring MVC?我们首先要搞清楚什么是 MVC?
2.MVC 和 SpringMVC
2.1 MVC 的定义
MVC 是 Model View Controller 的缩写,它是软件工程中的一种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分。
View(视图) : 指在应用程序中专门用来与浏览器进行交互,展示数据的资源.
Model(模型) : 是应用程序的主体部分,用来处理程序中数据逻辑的部分.
Controller(控制器) : 可以理解为一个分发器,用来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳回到哪一个视图。即用来连接视图和模型
比如去饭店吃饭:
客户进店之后,服务员来接待客户点餐,客户点完餐之后,把客户菜单交给前厅,前厅根据客户菜单给后厨下达命令。后厨负责做饭,做完之后,再根据菜单告诉服务员,这是 X 号餐桌客人的饭。
在这个过程中
服务员就是 View(视图), 负责接待客户,帮助客户点餐,以及把饭端到顾客面前
前厅就是 Controller(控制器), 根据用户的点餐情况,来选择给哪个后厨下达命令。
后厨就是 Model(模型), 根据前厅的要求来完成客户的用餐需求
2.2 SpringMVC 的定义
MVC 是一种架构设计模式,也是一种思想,而 Spring MVC 是对 MVC 思想的具体实现。但是,Spring MVC 还是一个 Web 框架。
总结来说,Spring MVC 是一个实现了 MVC 模式的 Web 框架。
所以,Spring MVC 主要关注有两个点:
MVC
Web 框架
Spring MVC 全称是 Spring Web MVC
其实,在创建 Spring Boot 项目时,我们勾选的 Spring Web 框架其实就是 Spring MVC 框架:
可以看到,Spring Web 的介绍是:
Build web, including RESTful, applications using Spring MVC. Uses Apache Tomcat as the default embedded container.
这时候可能有些学生就懵了,前面创建的不是 SpringBoot 项目吗?怎么又变成了 Spring MVC 项目?他们之间到底有着什么样的关系?
SpringBoot 是 2014 年发布的,Spring 是 2004 年发布的,在 2014 年发布之前,就不能用 Spring 实现 MVC 架构吗?显然不是了。
Spring Boot 只是实现 Spring MVC 的一种方式而已。
Spring Boot 可以添加很多依赖,借助这些依赖实现不同的功能。Spring Boot 通过添加 Spring Web MVC 框架,来实现 web 功能。
比如:厨房可以用来做饭,但真实实现做饭功能的是火以及各种做饭相关的食材和工具。厨房就好比是 SpringBoot,厨房可以装柜子,实现收纳功能,装燃气灶等,实现做饭功能。做饭这个事,就是 MVC,在几千年前,有火有食材就可以实现做饭。
不过 Spring 在实现 MVC 时,也结合自身项目的特点,做了一些改变,相对而言,下面这个图或许更加合适一些。
不过核心没变
比如上面的例子中,去饭店吃饭。一些饭店是前厅来负责接待客户,帮助客户点餐,也就是 Controller 来负责接收用户的请求.
2.3 再次理解 MVC 和 SpringMVC 一个项目并不是单纯的是 SpringBoot 项目,也不是单纯的是 SpringMVC 项目,他们之间是有交集的。
SpringBoot 是帮助我们快速搭建一个项目;SpringMVC 是项目中的一个模块,是我们使用中的一个依赖,这个依赖就是下面的代码:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
现在的 SpringMVC 把 MVC 的模式改变了一些:
SpringBoot 是创建 SpringMVC 的一种方式,创建 MVC 方式有很多
当前阶段,MVC 的概念发生了一些变化,后端开发人员不涉及前端的页面开发,所以也就没有 view 层
所以 view 又有了一层解释:之前返回的是视图,现在返回的是视图所需要的数据
如下:
3.学习 Spring MVC
3.1 学习 SpringMVC 的重点 既然是 Web 框架,那么当用户在浏览器中输入了 url 之后,我们的 Spring MVC 项目就可以感知到用户的请求,并给予响应。
咱们学习 Spring MVC,重点也就是学习如何通过浏览器和用户程序进行交互。主要分以下三个方面:
建立连接 :将用户(浏览器)和 Java 程序连接起来,也就是访问一个地址能够调用到我们的 Spring 程序。
请求 : 用户请求的时候会带一些参数,在程序中要想办法获取到参数,所以请求这块主要是 获取参数的功能.
响应 : 执行了业务逻辑之后,要把程序执行的结果返回给用户,也就是响应。
对于 Spring MVC 来说,掌握了以上 3 个功能就相当于掌握了 Spring MVC.
3.2 项目准备 Spring MVC 项目创建和 Spring Boot 创建项目相同,在创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项目。
创建项目时,勾选上 Spring Web 模块即可,如下图所示:
3.3 建立连接 在 Spring MVC 中使用 RequestMapping 注解来实现 URL 路由映射,RequestMapping 注解的作用就是浏览器连接程序,我们先来看看代码怎么写:
创建好一个 SpringBoot 项目后,再 main 路径下会有一个默认的 controller java 程序,实现了用户通过浏览器和程序的交互:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class BasicController {
@RequestMapping("/hello")
@ResponseBody
public String hello (@RequestParam(name = "name", defaultValue = "unknown user") String name) {
return "Hello " + name;
}
}
上述的 @RequestMapping("/hello") 中的 /hello 是一个子路径。
运行 main 路径下的主程序,再用浏览器搜索:127.0.0.1:8080/hello
3.3.1 RequestMapping 的路径使用 能够借助 @RequestMapping 注解为控制器类或者方法指定请求路径,进而让 Spring 知晓当接收到特定 URL 请求时该调用哪个方法。
当我们在类上添加 RequestMapping 后再按原来的路径搜索:
添加类的路径:http://127.0.0.1:8080/basic/hello,再次搜索:
3.3.2 请求 RequestMapping 的方式 再浏览器中我们只能使用 GET 请求,想用更多的请求只能借助 Postman 工具。
使用 postman 进行测试后发现 RequestMapping 可以满足 Get、Post 等几乎所有请求。
在 RequestMapping 中使用 method 属性。
这时再用 postman 测试,发现只能 get 请求能拿到数据
3.4 请求
3.4.1 什么是路径请求? 访问不同的路径,就是发送不同的请求。在发送请求时,可能会带一些参数,所以学习 Spring 的请求,主要是学习如何传递参数到后端以及后端如何接收。
咱们主要是使用浏览器和 Postman 来模拟传递参数。
后端开发人员无需过度关注如何传递参数,了解即可,实际开发中以 Postman 测试为主。
比如餐厅的厨师,不关注用户是在店里下单,还是外卖平台下单,或者小程序下单,只需要知道如何接收订单,根据订单做出对应的菜肴就可以了。
3.4.2 不传递参数 在上述的举例中如果没有传参设置的是默认值 @RequestParam(name = "name", defaultValue = "unknown user") String name
@RequestMapping("/hello")
@ResponseBody
public String hello (String name) {
return "接受到的参数是:" + name;
}
如果不传递参数,name 的默认值为 unknown user
@RequestMapping("/basic")
@Controller
public class BasicController {
@RequestMapping("/hello")
@ResponseBody
public String hello (String name) {
return "接受到的参数是:" + name;
}
}
引用类型不传参:搜索的路径为 127.0.0.1:8080/basic/hello
@RequestMapping("/hello")
@ResponseBody
public String hello (int age) {
return "接受到的参数是:" + age;
}
原因分析:int 是基本数据类型,基本数据类型是值类型,它们不能接受 null 值。像 byte、short、long、float、double、char、boolean 都是基本数据类型,都不能接受 null。
可以将基本数据类型替换为对应的包装类,包装类可以接受 null 值
@GetMapping("/hello")
@ResponseBody
public String hello (Integer age) {
if (age == null ) {
age = 0 ;
}
return "接受到的参数是:" + age;
}
使用 @RequestParam 的 defaultValue 属性为参数设置默认值。
@GetMapping("/hello")
@ResponseBody
public String hello (@RequestParam(value = "age", defaultValue = "0") int age) {
return "接受到的参数是:" + age;
}
3.4.3 传递单个参数 引用类型接收单个参数,在 Spring MVC 中直接用方法中的参数就可以,比如以下代码:
@RequestMapping("/basic")
@Controller
public class BasicController {
@RequestMapping("/hello")
@ResponseBody
public String hello (String name) {
return "接受到的参数是:" + name;
}
}
搜索地址:127.0.0.1:8080/basic/hello?name=zhangsan
3.4.4 传递 2 个参数
@RequestMapping("/hello")
@ResponseBody
public String hello (String name, Integer age) {
return "接受的 name 参数是:" + name + ",接受的 age 参数是:" + age;
}
(1)搜索地址:127.0.0.1:8080/basic/hello?name=zhangsan
(2)搜索地址:127.0.0.1:8080/basic/hello?age=20
(3)搜索地址:127.0.0.1:8080/basic/hello?age=20&name=zhangsan
(4)搜索地址:127.0.0.1:8080/basic/hello?name=zhangsan&age=20
3.4.5 传递对象 public class User {
private String name;
private Integer age;
public String getName () { return name; }
public void setName (String name) { this .name = name; }
public Integer getAge () { return age; }
public void setAge (Integer age) { this .age = age; }
@Override
public String toString () {
return "User{" + "name='" + name + '\'' + ", age=" + age + '}' ;
}
}
在 BasicController 类中添加如下方法:
@RequestMapping("/save_user")
@ResponseBody
public String saveUser (User u) {
return u.toString();
}
在浏览器中搜索:127.0.0.1:8080/basic/save_user?name=lisi&age=20
3.4.6 传递一个数组 @RequestMapping("/basic")
@Controller
public class BasicController {
@RequestMapping("/hello")
@ResponseBody
public String hello (String[] arrayName) {
return "接收到的参数是:" + Arrays.toString(arrayName);
}
}
在浏览器搜索:127.0.0.1:8080/basic/hello?arrayName=zhangsan,lisi,wangwu
当我们请求时,同一个参数赋值多个时,浏览器会帮我们封装为数组,然后传参。
运行后,在浏览器搜索:127.0.0.1:8080/basic/hello?arrayName=zhangsan&arrayName=lisi&arrayName=wangwu
当我们请求时,同一个参数有多个时,浏览器会帮我们封装为数组,然后传参。
3.4.7 传递一个集合 @RequestMapping("/basic")
@Controller
public class BasicController {
@RequestMapping("/hello")
@ResponseBody
public String hello (List<String> listName) {
return "接收到的参数 listName 是:" + listName.toString();
}
}
在浏览器搜索:127.0.0.1:8080/basic/hello?listName=zhangsan,lisi,wangwu
错误提示:未找到接口 java.util.List 的主构造函数或单个唯一构造函数。
通俗来说:浏览器把传递的参数封装成了数组,列表接收不了数组类型的参数
@RequestMapping("/basic")
@Controller
public class BasicController {
@RequestMapping("/hello")
@ResponseBody
public String hello (@RequestParam List<String> listName) {
return "接收到的参数 listName 是:" + listName.toString();
}
}
再次搜索:127.0.0.1:8080/basic/hello?listName=zhangsan,lisi,wangwu
再次搜索:127.0.0.1:8080/basic/hello?listName=zhangsan&listName=lisi&listName=wangwu
3.4.8 后端参数重命名
@RequestMapping("/hello")
@ResponseBody
public String hello (@RequestParam("name") String username) {
return "接受的 name 参数是:" + username;
}
浏览器搜索:127.0.0.1:8080/basic/hello?name=lisi
传参的是 name,为什么 username 也有值呢?
浏览器搜索:127.0.0.1:8080/basic/hello?username=lisi
把 required 属性改为 false 后就可以使用 username 了
@RequestMapping("/hello")
@ResponseBody
public String hello (@RequestParam(value = "name", required = false) String username) {
return "接受的 name 参数是:" + username;
}
浏览器搜索:127.0.0.1:8080/basic/hello?username=lisi
此时 username 无法获取值,username 只能复制 user 的值。
若需重命名,必须配合 @RequestParam 指定参数名。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online