文章目录
- [Ⅰ. 什么是 Spring MVC](#Ⅰ. 什么是 Spring MVC)
- [Ⅱ. 请求](#Ⅱ. 请求)
-
- [一、路由映射 `@RequestMapping`](#一、路由映射
@RequestMapping) -
- [📚 常见属性详解](#📚 常见属性详解)
- [① 指定 URL 路径(基本用法)](#① 指定 URL 路径(基本用法))
- [② 指定具体的请求方法](#② 指定具体的请求方法)
- [③ 指定多个 URL 和请求方法](#③ 指定多个 URL 和请求方法)
- [④ 带参数约束的请求映射](#④ 带参数约束的请求映射)
- [🔄 其它相关注解](#🔄 其它相关注解)
- [二、`Postman` 的使用](#二、
Postman的使用) - 三、注意事项
- [四、后端参数映射 `@RequestParam`](#四、后端参数映射
@RequestParam) - [五、传递 `json` 对象数据](#五、传递
json对象数据) -
- [① 使用 `Jackson` 原生接口](#① 使用
Jackson原生接口) - [② 使用注解 `@RequestBody`](#② 使用注解
@RequestBody)
- [① 使用 `Jackson` 原生接口](#① 使用
- [六、获取 URL 中的参数 `@PathVariable`](#六、获取 URL 中的参数
@PathVariable) - [七、上传文件 `@RequestPart` && `MultipartFile`](#七、上传文件
@RequestPart&&MultipartFile) - [八、获取 cookie 和 session](#八、获取 cookie 和 session)
-
- [① 原生接口获取 cookie](#① 原生接口获取 cookie)
- [② 使用注解 `@CookieValue`](#② 使用注解
@CookieValue) - [③ 设置和获取 session](#③ 设置和获取 session)
- 💥注意事项
- [九、获取报头 `@RequestHeader`](#九、获取报头
@RequestHeader)
- [一、路由映射 `@RequestMapping`](#一、路由映射
- [Ⅲ. 响应](#Ⅲ. 响应)
- 总结
- 拓展:Lombok

Ⅰ. 什么是 Spring MVC
首先 MVC 是 Model View Controller 的缩写,它是软件工程中的一种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分,如下图所示:

- View(视图):指在应用程序中专门用来与浏览器进行交互,展示数据的资源。
- Model(模型):是应用程序的主体部分,用来处理程序中数据逻辑的部分。
- Controller(控制器):可以理解为一个分发器,用来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳回到哪一个视图。即用来连接视图和模型。
而 Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从一开始就包含在 Spring 框架中。它的正式名称 SpringWeb MVC 来自其源模块的名称(Spring-webmvc),但它通常被称为 Spring MVC。
简单的说,Spring MVC 是对 MVC 思想的具体实现,它本质上是一个 Web 框架!
什么是
Servlet呢❓❓❓
Servlet是一种实现动态页面的技术。准确来讲Servlet是一套JavaWeb开发的规范,或者说是一套JavaWeb开发的技术标准。只有规范并不能做任何事情,必须要有人去实现它.所谓实现Servlet规范,就是真正编写代码去实现Servlet规范提到的各种功能,包括类、方法、属性等。Servlet规范是开放的,除了Sun公司,其它公司也可以实现Servlet规范,目前常见的实现了Servlet规范的产品包括Tomcat、Weblogic、Jetty、Jboss、WebSphere等,它们都被称为 "Servlet容器 ",用来管理程序员编写的Servlet类。
此外要区分,Spring Boot 是开发平台。Spring Boot 把 Spring MVC 包进来了,让我们用起来更轻松、更快速、更少配置,相当于 Spring Boot 是一个 "装修公司",而 Spring MVC 只是其中用来做 "Web 层装修"的技术。
| 名称 | 本质 | 作用 |
|---|---|---|
| Spring 核心(Spring Framework) | 🌱 IoC + AOP 的核心容器 | 管理 Bean、提供依赖注入、面向切面编程 |
| Spring MVC | 🌐 基于 Servlet 的 Web 框架 | 实现 Web 请求处理(Controller + DispatcherServlet) |
| Spring Boot | 🚀 快速开发脚手架 | 简化配置、自动装配、快速构建 Spring 应用 |
Ⅱ. 请求
一、路由映射 @RequestMapping
@RequestMapping 既可修饰类,也可以修饰方法,当修饰类和方法时,访问的地址是 类路径 + 方法路径。
@RequestMapping标识一个类 :设置映射请求的请求路径的初始信息
@RequestMapping标识一个方法 :设置映射请求请求路径的具体信息
java
@RequestMapping("/user")
@RestController
public class UserController {
@RequestMapping("/sayHi")
public String sayHi(){
return "hello,Spring MVC";
}
}
访问地址:http://127.0.0.1:8080/user/sayHi
📚 常见属性详解
| 属性 | 作用 | 示例 |
|---|---|---|
| value / path | 指定映射的 URL | /users |
| method | 指定请求方法 | RequestMethod.GET |
| params | 指定请求中必须包含某些参数值 | params="id" |
| headers | 指定请求中必须包含某些报头字段 | headers="Content-Type=application/json" |
| produces | 指定响应类型 | produces="application/json" |
| consumes | 指定请求的提交内容类型 | consumes="application/json" |
💥注意事项: spring 对于 List、Map、自定义类型等返回值,默认返回给前端的都是 json 格式 ,如果需要返回其它格式的响应,则需要通过 @RequestMapping 中的 produces 属性来设定!
① 指定 URL 路径(基本用法)
java
@RequestMapping("/login")
public String loginPage() {
return "login.html";
}
② 指定具体的请求方法
java
@RequestMapping(value = "/user", method = RequestMethod.GET)
public User getUser() {
return new User();
}
✅ 现代推荐 :直接用更精简的注解,如 @GetMapping("/user")
③ 指定多个 URL 和请求方法
用 {} 来包含多个 URL 和请求方法:
java
@RequestMapping(value = {"/login", "/signin"}, method = {RequestMethod.GET, RequestMethod.POST})
public String login() {
return "login";
}
④ 带参数约束的请求映射
java
@RequestMapping(value = "/search", params = "q")
public String search(@RequestParam String q) {
return "搜索关键词:" + q;
}
🔄 其它相关注解
🔔 Spring 4.3 之后推荐使用这些简化版本,更清晰。
| 新注解 | 作用 | 等价于 |
|---|---|---|
| @GetMapping | 处理 GET 请求 | @RequestMapping(method = RequestMethod.GET) |
| @PostMapping | 处理 POST 请求 | 同上 |
| @PutMapping | 处理 PUT 请求 | 同上 |
| @DeleteMapping | 处理 DELETE 请求 | 同上 |
二、Postman 的使用
在使用 postman 传参的时候,通常有几种格式,这里列举三种陌生的:
- form-data (完整格式:
multipart/form-data)- 表单提交的数据,通常用于提交图片、文件 等,对应
Content-Type: multipart/form-data。
- 表单提交的数据,通常用于提交图片、文件 等,对应
- x-www-form-urlencoded
- 表单提交的数据,通常用于提交纯文本比如账号、密码 等,对应
Content-Type: application/x-www-from-urlencoded。
- 表单提交的数据,通常用于提交纯文本比如账号、密码 等,对应
- raw
- 可以上传任意格式的文本 ,可以上传
text、json、xml、html等。
- 可以上传任意格式的文本 ,可以上传
三、注意事项
访问不同的路径,就是发送不同的请求。在发送请求时,可能会带一些参数,所以学习 Spring 的请求,主要是学习如何传递参数到后端以及后端如何接收,这里主要是使用浏览器和 Postman 来模拟。
- 使用基本类型 来接收参数时,参数必须传 (除
boolean类型),否则会报500错误。 - 类型不匹配时,会报
400错误。 - 如果只指定了
URL路径而没有别的参数的话,则可以忽略属性value,反之则必须加上! - 当有多个参数时,前后端进行参数匹配时,是以参数的名称进行匹配的,因此参数的位置是不影响后端获取参数的结果。
四、后端参数映射 @RequestParam
-
@RequestParam应用于以下场景:-
前端通过 form表单 、GET请求参数 、或 POST的
x-www-form-urlencoded方式提交 -
参数在 URL中 或 key-value格式 中出现,如:
Properties/api/user?id=123&name=Tom -
-
某些特殊的情况下,前端传递的参数
key和我们后端接收的key可以不一致,比如前端传递了一个time给后端,而后端是使用createtime字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,就可以使用@RequestParam来重命名前后端的参数值,需要注意使用@RequestParam之后参数就默认变成了必传参数,要设置为非必传参数的话,要指定参数required=false。java@RequestMapping("/d3") public String d3(@RequestParam(value="time", required=false) String createtime) { // 将time重命名为createtime,只对后端有效 return createtime; } -
在传递集合参数 的时候,需要使用
@RequestParam来绑定参数关系 ,因为默认情况下请求中参数名相同的多个值是封装到数组的,而如果要封装到集合的话,则需要用@RequestParam指定!java@RequestMapping("/d5") public String d5(@RequestParam List<String> list) { return list.toString(); }
五、传递 json 对象数据
Java 中常见的 JSON 库如下所示:
| 库名 | 速度 | 易用性 | Spring兼容 | 特点 |
|---|---|---|---|---|
| Jackson | ⭐⭐⭐⭐ | ⭐⭐⭐ | ✅ 默认支持 | 强大、全面、Spring首选 |
| Gson | ⭐⭐⭐ | ⭐⭐⭐⭐ | ❌ | 轻量、适合工具型项目 |
| Fastjson2 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ❌ | 极速、国内常用、需注意版本安全 |
| org.json | ⭐⭐ | ⭐⭐ | ❌ | 基础用法简单 |
其中 Spring Boot 内置了 Jackson,所以不需要引入依赖,只需要使用其核心类 ObjectMapper 来进行对象和 json 字符串的转化即可!
① 使用 Jackson 原生接口
这种操作一般不用,除非有特殊需求!
java
public void ObjectToJson() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper(); // 创建jackson的核心类
// writeValueAsString:将对象转化为JSON字符串
StudentInfo stu = new StudentInfo();
stu.setName("lirendada");
stu.setAge(18);
stu.setPasswd("123123");
String jsonstr = mapper.writeValueAsString(stu);
System.out.println("序列化结果:" + jsonstr);
// readValue:将JSON字符串转化为对象
StudentInfo new_stu = mapper.readValue(jsonstr, StudentInfo.class);
System.out.println("反序列化结果:" + new_stu);
}
② 使用注解 @RequestBody
在 Spring 项目中,JSON 的序列化/反序列化工作几乎都由 Spring 自动完成 ,只需要使用 @RequestBody 即可,除非业务逻辑中需要特殊的 JSON 操作,否则一般无需手动操作 ObjectMapper。
java
@RequestMapping("/demo4")
@RestController
public class demo4 {
// 请求 JSON → Java 对象(反序列化)
@RequestMapping("/saveuser")
public String saveUser(@RequestBody StudentInfo stu) {
return "json对象保存成功:" + stu.toString();
}
// Java 对象 → JSON 响应(序列化)
@RequestMapping("/getuser")
public StudentInfo getUser() {
// spring会自动将StudentInfo转化为JSON响应给前端
return new StudentInfo("lirendada", 18, "123123");
}
}
@RequestBody 通常处理以下场景:
- 前端使用 JSON 、XML 发送结构化数据(如使用 Axios、Fetch 或 Postman)
- 请求头为
Content-Type: application/json
六、获取 URL 中的参数 @PathVariable
首先需要在 @RequestMapping 中使用 {} 匹配一下 URL 中的参数 ,然后在方法参数列表中用 @PathVariable 指定对应的参数!
注意这个参数顺序是无序 的,并且如果方法参数要用别名,可以使用 @PathVariable 的 value 属性进行绑定!
java
@RequestMapping("/url/{id}/{name}")
public String pathvar(@PathVariable Integer id,
@PathVariable("name") String username) // 指定别名为username
{
return "解析参数id:" + id + ", name:" + username;
}

七、上传文件 @RequestPart && MultipartFile
MultipartFile是Spring定义的一个接口,表示上传的一个文件对象,它封装了文件上传时的所有关键信息,比如文件名、内容、文件大小、MIME类型等。@RequestPart通常处理前端通过multipart/form-data提交的数据,既有文件也有 JSON。
java
@PostMapping("/upload")
public String upload(@RequestPart("file") MultipartFile file,
@RequestPart("user") User user) throws IOException {
System.out.println(file.getOriginalFilename()); // 获取文件原名
System.out.println(file.getName()); // 获取请求时的键名
System.out.println(file.getContentType()); // 获取文件类型
// 将文件上传到指定路径
file.transferTo(new File("E:/杂物文档/" + file.getOriginalFilename()));
return "接收到的文件名为:" + file.getOriginalFilename();
}
八、获取 cookie 和 session
Cookie 和 Session 之间主要是通过 SessionID 关联起来的,SessionID 是 Cookie 和 Session 之间的桥梁,如下图所示:

Spring MVC 是基于 ServletAPI 构建的原始Web框架,是在 Servlet 的基础上实现的.
其中 HttpServletRequest、HttpServletResponse 是 Servlet 提供的两个类,同时也是 Spring MVC 方法的内置对象,需要时直接在方法中添加声明即可!
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。HttpServletResponse对象代表服务器的响应,HTTP响应的信息都在这个对象中,比如向客户端发送的数据、响应头、状态码等,通过这个对象提供的方法,可以获得服务器响应的所有内容。
① 原生接口获取 cookie
获取 cookie 本质就是通过 HttpServletRequest 的接口来获得!
java
@RequestMapping("/d1")
public String getcookie1(HttpServletRequest req) {
// 获取请求中的所有cookie,使用数组的时候记得判断是否为空
Cookie[] cookies = req.getCookies();
if(cookies != null) {
for(Cookie cookie : cookies) {
System.out.println(cookie.getName() + ": " + cookie.getValue());
}
}
return "返回cookies成功!";
}

② 使用注解 @CookieValue
注意如果没有在该注解中指定 cookie 的名称的话,则默认只能拿到一个 cookie!
java
@RequestMapping("/d2")
public String getcookie2(@CookieValue("liren") String liren,
@CookieValue("asd") String asd) {
return "liren: " + liren + "<br>asd: " + asd;
}

③ 设置和获取 session
三种方式,分别用到 HttpServletRequest 类的 getSession()、参数列表中 HttpSession session 接收参数、注解 @SessionAttribute,如下所示:
java
/**
* 获取session对象,根据是否为空判断要不要创建新session
*/
@RequestMapping("/setsession")
public String setSession(HttpServletRequest req) {
// 先获取session对象,设置为false,则不存在session就返回null,用于判断是否过期
HttpSession session = req.getSession(false);
if(session == null) {
// 过期了,要创建新的session对象
System.out.println("超时了!");
session = req.getSession(true); // 这次获取session对象用true,则不存在会创建
session.setMaxInactiveInterval(5); // 设置会话过期时间,单位为秒
}
session.setAttribute("liren", "lirendada_love_yt");
return "session设置成功";
}
/**
* 方式一:使用 HttpServletRequest 类的 getSession()
*/
@RequestMapping("/g1")
public String getsession1(HttpServletRequest req, HttpServletResponse resp) {
HttpSession session = req.getSession(); // 默认为true,不存在会创建新session
if(session != null && session.getAttribute("liren") != null) {
return "liren: " + session.getAttribute("liren");
}
return "null";
}
/**
* 方式二:直接在参数列表中获取HttpSession对象
*/
@RequestMapping("/g2")
public String getsession2(HttpSession session) {
if(session != null && session.getAttribute("liren") != null) {
return "liren: " + session.getAttribute("liren");
}
return "null";
}
/**
* 方式三:使用注解 @SessionAttribute
*/
@RequestMapping("/g3")
public String getsession3(@SessionAttribute String liren) {
return "liren: " + liren;
}
💥注意事项
- 每次访问
HttpSession的实际内容时(比如读写属性、调用方法等)都会自动刷新它的失效倒计时 ,这个失效倒计时可以通过setMaxInactiveInterval(int s)进行设置,单位是秒。 sessionid在第一次创建HttpSession对象的时候生成 ,并且不需要手动在HttpServletResponse中设置 ,因为底层容器Servlet会自动设置!- 通过
getSession(boolean iscreate)中的iscreate参数可以灵活处理不同情况:- 在需要第一次创建
HttpSession对象的场景中,通常让iscreate为true,表示对象不存在时候创建新对象。 - 其它场景比如获取
HttpSession对象的时候,通常就让iscreate为false,这样子就不会创建新对象。
- 在需要第一次创建
九、获取报头 @RequestHeader
java
/**
* 方式一:使用HttpServletRequest的getHeader()方法
*/
@RequestMapping("/g1")
public String getHeader1(HttpServletRequest req) {
return "User-Agent: " + req.getHeader("User-Agent");
}
/**
* 方式二:使用注解@RequestHeader
*/
@RequestMapping("/g2")
public String getHeader2(@RequestHeader("User-Agent") String agent) {
return "User-Agent: " + agent;
}
Ⅲ. 响应
-
@RestController指定这是一个进行了路由映射的类,并且指定该类返回非视图数据,而不是视图!-
Spring会对所有的类进行扫描,如果类加了注解@RestController,Spring才会去看这个类里面的方法有没有加@RequestMapping这个注解,当然他的作用不止这一点,后面详细讲!
java@RestController public class demo { @RequestMapping("hello") public String func() { return "liren!"; } }-
实际上
@RestController = @Controller + @ResponseBody,这是为了实现 "前后端分离" 而引入的,因为现在前端大部分不需要后端来做,所以后端只需要返回前端约定好的数据即可,所以现在一般都直接用@RestController来指定返回非视图数据 ,而单独使用@Controller的话则返回的是视图。@ResponseBody:可以放在类或者方法上面,表示类或者方法返回的是非视图数据,即返回一个 text/html 数据。@Controller:定义一个控制器,在spring框架启动时加载,把这个对象交给spring管理,也就是进行路由映射。
-
-
什么情况下响应的是 json 格式❓❓❓
- 控制器加了
@RestController或@ResponseBody
返回值类型 返回 JSON 格式? 示例结果 Map<String, ?> ✅ 是 JSON 对象 List / 数组 ✅ 是 JSON 数组 Object ✅ 是 JSON 对象 String ⚠️ 特殊处理 默认会被当成字符串文本返回,而不是 JSON java@ResponseBody @RequestMapping("/returnjson") public Map<String, String> returnjson() { HashMap<String, String> table = new HashMap<>(); table.put("java", "good"); table.put("cpp", "not good"); table.put("redis", "not bad"); return table; } - 控制器加了
-
设置响应状态码 ,使用
HttpServletResponse对象调用setStatus()即可。- 注意:状态码并不影响响应页面的展示!
-
设置响应报头 ,其中有些报头,比如设置响应类型,可以使用注解
@RequestMapping中的属性produces,而其它报头需要通过HttpServletResponse对象调用setHeader()来设置。 -
常见的响应格式方法如下所示:
| 场景类型 | 推荐返回方式 |
|---|---|
| 简单文本或标志返回("true"/"false") | ✅ String + produces="text/html" |
| 正常 REST 接口返回 JSON | ✅ @RestController + 返回对象/Map/List |
| 返回模板页面 | ✅ @Controller + return "xxx.html" |
| 要求精确控制响应头、状态码 | ✅ ResponseEntity<String> |
总结

拓展:Lombok
我们写一个 Java 实体类时,常常需要写一堆 Getter、Setter、构造方法、toString、equals、hashCode 等等,非常冗长,而 Lombok 可以 自动生成这些代码,你只需要写个注解!
| 注解 | 功能 |
|---|---|
| @Getter / @Setter | 自动生成 getter/setter 方法 |
| @ToString | 自动生成 toString() 方法 |
| @EqualsAndHashCode | 自动生成 equals() 和 hashCode() 方法 |
| @NoArgsConstructor | 自动生成无参构造器 |
| @AllArgsConstructor | 自动生成全参构造器 |
| @RequiredArgsConstructor | 自动生成包含 final 字段的构造器 |
| @Data | 相当于同时加了:@Getter、@Setter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor |
| @Builder | 生成建造者模式的代码 |
| @Slf4j | 自动生成日志对象(log),方便日志打印 |
可以通过该网站引入依赖:https://mvnrepository.com/artifact/org.projectlombok/lombok
xml
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
