【SpringMVC】Spring MVC 核心全解析:从 MVC 思想到 Web 交互(请求、响应、参数传递全实践)
文章目录
- 一.Spring Web MVC
- 1.什么是Spring Web MVC
- 2.MVC的定义
- 3.什么是Spring MVC
- 二.学习Spring MVC
- 1.建立连接
- @RequestMapping 注解介绍
- @RequestMapping 使用
- @RequestMapping 是 GET 还是 POST 请求?
- Postman详细介绍
- 传参(4种)
- 2.请求
- 1).传递单个参数
- 2).传递多个参数
- 3).传递对象
- 4).后端参数重命名(后端参数映射)
- 5).非必传参数设置
- 6).传递数组
- 7).传递集合
- 8).传递JSON数据
- 9).传递JSON对象
- 10).获取URL中参数@PathVariable
- 11).上传文件 @RequestPart
一.Spring Web MVC
1.什么是Spring Web MVC
MVC官方文档
Spring Web MVC是Spring框架中的一个用来做网站开发的部分,它是基于Servlet技术的。
虽然它的正式名字叫“Spring Web MVC”,但大家一般都简称它“SpringMVC”。
- Servlet
Servlet是一种技术,用来创建动态网页。
它其实是一种规范,也就是规定了如何写Java Web应用的规则。但单靠规范本身不能做任何事,必须要开发者根据这些规则写代码,才能实现它的功能。
很多公司都可以根据这个规范来开发相应的软件,比如Tomcat、Weblogic、Jetty等,它们被叫做“Servlet容器”。
这些容器的作用就是管理和运行开发者写的Servlet代码。
Spring Web MVC 是一个Web框架,下面现在都是简称为 Spring MVC
2.MVC的定义
MVC是Model View Controller的缩写,它是软件工程中的一种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分。

3.什么是Spring MVC
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 Boot只是实现Spring MVC的其中一种方式而已。
- Spring Boot可以添加很多依赖,借助这些依赖实现不同的功能。Spring Boot通过添加Spring Web MVC框架,来实现web功能
现在 Spring在实现MVC的时候,也结合了自身项目的特点,做了一些改变
现在请求不再先走 view 再走 controller,请求可以直接发送到 controller;
controller 在受到 model 传回来的响应后,可以返回给 view,也可以直接返回浏览器;
后端开发一般就不会让请求和响应交互过程走 view,不过核心没变,比如上面的例子中,去饭店吃饭:
- 一些饭店是前厅来负责接待客户,帮助客户点餐,也就是 Controller 来负责接收用户的请求。
- 去公司面试,直接由面试官来接待候选人,省去了HR中间的交接过程。
二.学习Spring MVC
既然是Web框架,那么当用户在浏览器中输入了url之后,我们的Spring MVC项目就可以感知到用户的请求,并给予响应。
咱们学习Spring MVC,重点也就是学习如何通过浏览器和用户程序进行交互。主要分以下三个方面:
-
- 建立连接:让用户(浏览器)能找到并访问你的 Spring 程序,简单来说就是让用户输入网址时能够打开你的网页。
-
- 请求:用户在网页上点击、输入等操作时,会发送一些信息(比如表单数据)。你的程序需要能接收到这些信息,以便做进一步处理。
-
- 响应:当程序处理完用户的请求后,需要把处理结果(比如网页内容)返回给用户,这就是响应。
总结一下:就是让用户通过浏览器访问程序,获取信息,再把结果返回给用户。
对于Spring MVC来说,掌握了以上3个功能就相当于掌握了Spring MVC。
- 响应:当程序处理完用户的请求后,需要把处理结果(比如网页内容)返回给用户,这就是响应。
就是让用户通过浏览器访问程序,获取信息,再把结果返回给客户
1.建立连接
在Spring MVC中使用 @RequestMapping 来实现 URL 路由映射,也就是浏览器连接程序的作用
我们先来看看代码怎么写,创建一个 UserController 类,实现用户通过浏览器和程序的交互,具体实现代码如下:

方法名和路径名称无需一致
接下来访问: http://127.0.0.1:8080/user/Hello, 就可以看到程序返回的数据了

这个类是如何启动的呢? => @SpringBootApplication这个启动类里的main映射来启动的
类似一种key-value key:类 value:路径
通过@RestController这个注解来告诉Spring扫描
建议给所有的类都加类路径 => @RequestMapping(“/user”) =>来标记类的名字(可读性高)

@RequestMapping 注解介绍
@RequestMapping 是 Spring Web MVC 应用程序中最常被用到的注解之一,它是用来注册接口的路由映射的.
表示服务收到请求时,路径为 /uesr/Hello 的请求就会调用 Hello 这个方法的代码.
路由映射: 当用户访问一个 URL 时,将用户的请求对应到程序中某个类的某个方法的过程就叫路由映射.
既然 @RequestMapping 已经可以达到我们的目的了,我们为什么还要加 @RestController 呢?
我们把 @RestController 去掉,再来访问一次:

可以看到,程序报了404,找不到该页面.
这就是 @RestController 起到的作用.
一个项目中,会有很多类,每个类可能有很多的方法,Spring程序怎么知道要执行哪个方法呢?
Spring会对所有的类进行扫描,如果类加了注解@RestController,Spring才会去看这个类里面的方法有没有加 @RequestMapping 这个注解,当然他的作用不止这一点,咱们先用,后面再详细讲
@RequestMapping 使用
@RequestMapping 既可修饰类,也可以修饰方法,当修饰类和方法时,访问的地址是类路径 + 方法路径.
@RequestMapping标识一个类:设置映射请求的请求路径的初始信息
@RequestMapping标识一个方法:设置映射请求请求路径的具体信息
上面我们已经演示喽~~

注意:
@RequestMapping 的URL 路径最前面加不加 / (斜杠)都可以, Spring程序启动时, 会进行判断, 如果前面没有加 / , Spring会拼接上一个 /
不过,通常情况下我们还是加上 / 比较规范
@RequestMapping 是 GET 还是 POST 请求?
我们来测试一下就知道结论了
GET请求:
浏览器发送的请求类型都是get,通过以上案例,可以看出来 @RequestMapping 支持get请求.
POST 请求:
我们通过form表单来构造请求:
创建test.html, html代码:


但是我们作为后端开发人员,想要测试还有通过form表单,有点麻烦
这里介绍一个开发中常用的工具 postman


那如何指定GET或者POST类型呢?
指定GET/POST方法类型
我们可以显示的指定@RequestMapping 来接收POST的情况,如下所示:

Postman详细介绍
从上面的案例中,也发现了一个新的问题,就是我们测试后端方法时,还需要去写前端代码.这对我们来说,是一件麻烦又痛苦的事情.
随着互联网的发展,也随着项目难度的增加,企业也按照开发的功能,把人员拆分成了不同的团队.界面显示交给"前端开发工程师",业务逻辑的实现交给 “后端开发工程师”.
后端开发工程师,不要求也不需要掌握前端技能了.
那后端开发工程师,如何测试自己的程序呢? – 使用专业的接口测试工具,接下来我们来学习
讨论Postman的使用.
传参(4种)
1.普通传参 => URL 其中查询字符串就是请求的参数
2. form-data(完整表示为: multipart/form-data)
表单提交的数据, 在 form 标签中加上enctyped="multipart/form-data", 通常用于提交图片/文件. 对应Content-Type: multipart/form-data
3. form-data(完整表示为: multipart/form-data)
表单提交的数据, 在 form 标签中加上enctyped="multipart/form-data", 通常用于提交图片/文件. 对应Content-Type: multipart/form-data
4. raw
可以上传任意格式的文本,可以上传text、json、xml、html等
2.请求
访问不同的路径,就是发送不同的请求.在发送请求时,可能会带一些参数,所以学习Spring的请求,主要是学习如何传递参数到后端以及后端如何接收.
传递参数,咱们主要是使用浏览器和Postman来模拟.
后端开发人员无需过度关注如何传递参数,了解即可,实际开发中以Postman测试为主.
比如餐厅的厨师,不关注用户是在店里下单,还是外卖平台下单,或者小程序下单,只需要知道如何接收订单,根据订单做出对应的菜肴就可以了.
1).传递单个参数
接收单个参数,在 Spring MVC 中直接用方法中的参数就可以,比如以下代码:
通过浏览器发送请求并传参
可以看到,后端程序正确拿到了name参数的值
Spring MVC 会根据方法的参数名,找到对应的参数,赋值给方法
如果参数不一致,是获取不到参数的
比如请求URL:http://127.0.0.1:8080/param/m1?name1=spring
响应结果为:
注意事项
使用基本类型来接收参数时,参数必须传(除boolean类型),否则会报500错误;类型不匹配时,会报400错误.
①.正常传递参数
通过Fiddler观察请求和响应,HTTP响应状态码为200,Content-Type为text/html
②.不传递参数
③.传递参数不匹配
对于包装类型,如果不传对应参数,Spring 接收到的数据则为null
所以企业开发中,对于参数可能为空的数据,建议使用包装类型
2).传递多个参数
如何接收多个参数呢?
和接收单个参数一样,直接使用方法的参数接收即可,使用多个形象

注意:当有多个参数时,前后端进行参数匹配时,是以参数 名称进行匹配的,因此参数的位置是不想影响后端获取参数的
3).传递对象
如果参数比较多时,方法声明就需要有很多形参.并且后续每次新增一个参数,也需要修改方法声明.
我们不妨把这些参数封装为一个对象.
Spring MVC 也可以自动实现对象参数的赋值,比如 Person 对象:
public class Person {private int id;private String name;private String password;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "Person{" +"id=" + id +", name='" + name + '\'' +", password='" + password + '\'' +'}';}
}
传递对象代码实现:


Spring 会根据参数名称自动绑定到对象的各个属性上,如果某个属性未传递,则赋值为null(基本类型则赋值为默认初识值,比如int类型的属性,会被赋值为0)
4).后端参数重命名(后端参数映射)
某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不一致,比如前端传递了一个time 给后端,而后端是使用 createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使用 @RequestParam 来重命名前后端的参数值.
具体示例如下,后端实现代码:


如果使用createtime进行参数传递呢?


控制台打印日志显示:请求参数"time"不存在
可以得出结论:
-
- 使用
@RequestParam进行参数重命名时, 请求参数只能和@RequestParam声明的名称一致,才能进行参数绑定和赋值.
- 使用
-
- 使用
@RequestParam进行参数重命名时,参数就变成了必传参数.
- 使用
5).非必传参数设置
如果我们的实际业务前端的参数是一个非必传的参数,针对上述问题,如何解决呢?
先来了解下参数必传的原因,我们查看 @RequestParam 注解的实现源码



可以看到,添加required=false之后, time前面也加了key,变成了 value = "time"
注解属性赋值时,没有指明key的话,默认为value属性.
如果需要有多个属性进行赋值时,需要写上key
6).传递数组
Spring MVC 可以自动绑定数组参数的赋值
后端实现代码:



7).传递集合
集合参数:和数组类似,同一个请求参数名有为多个,且需要使用 @RequestParam 绑定参数关系
默认情况下,请求中参数名相同的多个值,是封装到数组.如果要封装到集合,要使用 @RequestParam 绑定参数关系
请求方式和数组类似:

8).传递JSON数据
JSON概念
JSON:JavaScript Object Notation 【JavaScript 对象表示法】
JSON是一种轻量级的数据交互格式.它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
简单来说:JSON就是一种数据格式,有自己的格式和语法,使用文本表示一个对象或数组的信息,因此JSON本质是字符串. 主要负责在不同的语言中数据传递和交换.
JSON语法
JSON 是一个字符串,其格式非常类似于 JavaScript 对象字面量的格式
我们先来看一段JSON数据
{"squadName": "Super hero squad","homeTown": "Metro City","formed": 2016,"secretBase": "Super tower","active": true,"members": [{"name": "Molecule Man","age": 29,"secretIdentity": "Dan Jukes","powers": ["Radiation resistance", "Turning tiny", "Radiation blast"]}, {"name": "Madame Uppercut","age": 39,"secretIdentity": "Jane Wilson","powers": ["Million tonne punch", "Damage resistance", "Superhuman reflexes"]}, {"name": "Eternal Flame","age": 1000000,"secretIdentity": "Unknown","powers": ["Immortality", "Heat Immunity", "Inferno", "Teleportation", "Interdimensional travel"]}]
}
也可以压缩表示
{"squadName":"Super hero squad","homeTown":"Metro City","formed":2016,"secretBase":"Super tower","active":true,"members":[{"name":"Molecule Man","age":29,"secretIdentity":"Dan Jukes","powers":["Radiation resistance","Turning tiny","Radiation blast"]},{"name":"Madame Uppercut","age":39,"secretIdentity":"Jane Wilson","powers":["Million tonne punch","Damage resistance","Superhuman reflexes"]},{"name":"Eternal Flame","age":1000000,"secretIdentity":"Unknown","powers":["Immortality","Heat Immunity","Inferno","Teleportation","Interdimensional travel"]}]}
JSON的语法:
- 数据在键值对(Key/Value)中
- 数据由逗号
,分隔- 对象用
{}表示- 数组用
[]表示- 值可以为对象,也可以为数组,数组中可以包含多个对象
JSON的两种结构
- 对象:大括号
{}保存的对象是一个无序的键值对集合.一个对象以左括号{开始,右括号}结束。每个"键"后跟一个冒号:,键值对使用逗号,分隔- 数组:中括号
[]保存的数组是值(value)的有序集合.一个数组以左中括号[开始,右中括号]结束,值之间使用逗号,分隔。
1 {"name":"admin","age":18}
2 ["hello", 3.1415, "json"]
3 [{"name":"admin","age":18},{"name":"root","age":16},{"name":"张三","age":20}]
以上都是合法的JSON数据

JSON字符串和Java对象互转
JSON本质上是一个字符串,通过文本来存储和描述数据
Spring MVC框架也集成了JSON的转换工具,我们可以直接使用,来完成JSON字符串和Java对象的互转
本质上是jackson-databind提供的功能, Spring MVC框架中已经把该工具包引入了进来,咱们直接使用即可,如果脱离Spring MVC使用,需要引入相关依赖

使用ObjectMapper对象提供的两个方法,可以完成对象和JSON字符串的互转
writeValueAsString: 把对象转为JSON字符串
readValue: 把字符串转为对象
JSON优点
-
- 简单易用: 语法简单,易于理解和编写,可以快速地进行数据交换
-
- 跨平台支持: JSON可以被多种编程语言解析和生成,可以在不同的平台和语言之间进行数据交换和传输
-
- 轻量级: 相较于XML格式,JSON数据格式更加轻量级,传输数据时占用带宽较小,可以提高数据传输速度
-
- 易于扩展: JSON的数据结构灵活,支持嵌套对象和数组等复杂的数据结构,便于扩展和使用
-
- 安全性: JSON数据格式是一种纯文本格式,不包含可执行代码,不会执行恶意代码,因此具有较高的安全性
基于以上特点,JSON在Web应用程序中被广泛使用,如前后端数据交互、API接口数据传输等.
9).传递JSON对象
接收JSON对象,需要使用 @RequestBody 注解
RequestBody: 请求正文,意思是这个注解作用在请求正文的数据绑定,请求参数必须在写在请求正文中
后端实现:




10).获取URL中参数@PathVariable
path variable: 路径变量
和字面表达的意思一样,这个注解主要作用在请求URL路径上的数据绑定
默认传递参数写在URL上,SpringMVC就可以获取到
后端实现代码:


如果方法参数名称和需要绑定的URL中的变量名称一致时,可以简写,不用给@PathVariable的属性赋值,如上述例子中的id变量
如果方法参数名称和需要绑定的URL中的变量名称不一致时,需要@PathVariable的属性value赋值,如上述例子中的userName变量.
11).上传文件 @RequestPart




















