本文将来简单介绍一下SpringMVC中的常见注解
1. 路由映射:一切连接的起点
@RequestMapping
这是最常被用到的注解,它是用来注册接口的路由映射的。简单的说,就是把浏览器输入的 URL 对应到你代码里的某个类或方法。
场景化铺垫 : 想象你在双十一凌晨疯狂抢购,你点击"结算"按钮的那一刻,浏览器发出的请求必须精准撞进服务器对应的"处理订单"的方法里,这就是
@RequestMapping在后台立的功。
java
@RestController
@RequestMapping("/hello")
public class UserController {
@RequestMapping ("/sayHi")
public String sayHi(){
return "hello ,Spring MVC";
}
}
访问 http://127.0.0.1:8080/hello/sayHi 即可调用此方法,url的路径就是我们在类前面添加的注解路径("/hello") + 方法前的注解路径("/sayHi"),
在浏览器中直接输入对应的网址,即可观察到return 的结果

当然,也可以使用Postman这样的工具来观察接口的返回结果
避坑指南:
-
URL 路径前面加不加
/(斜杠)都可以,Spring 启动时会自动判断并拼接,但是还是建议在路径前添加 / -
它既可以修饰类(设置初始路径),也可以修饰方法(设置具体路径)。

- 默认它支持 GET、POST 等所有请求方式。如果想限定某种方式,需要设置
method属性。

不过除了上面直接在方法上面修改注解的的方式之外,也可以在方法的参数列表中添加对应的method来限制请求的类型,

此时再尝试发送post请求就能正常处理了
2. 参数传递:别再拿不到数据了!
在和用户程序交互时,获取参数是核心。这里有几个注解必须掌握:
@RequestParam(后端参数重命名)
场景化铺垫 : 前端小哥在页面上定义的参数名叫
time,但你在后端为了规范非要叫createtime。这时候如果不加处理,数据根本传不过来,直接返回null让你怀疑人生!
java
@RequestMapping("/m4")
public Object method_4(@RequestParam(value = "time", required = false) String createtime) {
return "接收到参数createtime:" + createtime;
}
注意 :使用了 @RequestParam 后,该参数默认变为必传 。如果想设置成非必传,记得加上 required = false。


@RequestBody(接收 JSON 数据)
场景化铺垫 : 现在的开发流行"前后端分离",前端传过来的往往是一个复杂的 JSON 对象。如果你还是像以前那样直接传参,后端拿到的对象属性全都是
null!
java
@RequestMapping("/m7")
public Object method7(@RequestBody Person person) {
return person.toString();
}
敲黑板 :接收 JSON 对象必须 使用 @RequestBody,否则数据无法成功绑定。
比如我们先定义一个person类对象,即可就可以给通过json的方式来对person中的属性进行赋值,以下方法过于繁琐,后面可以使用lombok插件的方式来自动为我们在编译时生成对应属性获取方法
java
public class Person {
private int id;
private String name;
private int age;
private String address;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public int getAge() {
return age;
}
public String getAddress() {
return address;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}

@PathVariable(获取 URL 中的变量)
这个注解主要作用在请求 URL 路径上的数据绑定。
java
// 访问路径类似:/hello/m8/5/zhangsan
@RequestMapping("/m8/{id}/{name}")
public String method8(@PathVariable Integer id, @PathVariable("name") String userName) {
return "解析参数id:" + id + ", name: " + userName;
}

不过这里也涉及到一点,那就是把int类型的id定义为包装类型Integer,为什么不定位int呢?其实这是为了避免状态码500异常 ,5XX的状态码一般被认为是服务器处理失败
为何会出现500异常?如果把null传递给 int ,就会出现类型不匹配,这在前端参数传递中如果传递失败就会出现.比如把int类型的实际传递一个String,但是当我们使用Integer包装类型,则会只出现400等4开头的状态码
3. 会话与 Header:识别"自己人"
@CookieValue & @SessionAttribute
场景化铺垫: 医院看病需要"就诊卡"。你第一次挂号得到这张卡(Session 创建),以后去抽血、拍片只需要刷一下卡(携带 Cookie/SessionID),医生就能识别你的身份。在 Web 开发中,这就是会话机制。
HTTP无连接,每次客户端与服务器建立连接服务器都无需记住客户端的状态,这是出于传输效率考虑的.但是此时却使用了会话机制来保存状态,这难道不是与"无连接",的特性相违背吗?
实则不然,试想一下,你每次轻车熟路的点击一个你登陆过很多次的网站,但是每次都要求你输入登录账号和密码.这给人的体验自然是极其不良好的,http的无连接是在底层架构的选择上实现的,是基于TCP的无连接特性来保证高效传输,但是在业务上是需要使得其变得有状态,这就需要cookie和session来配合实现
这种设计逻辑如下:
-
HTTP(基础层): 保持无状态,确保传输的轻量和高并发能力。
-
Cookie/Session(应用层): 像是一个"临时身份证"。服务器不主动记你,而是发给你一个编号(Session ID),你每次来的时候自己带上。
| 维度 | HTTP 无状态 (Stateless) | Cookie/Session 机制 |
|---|---|---|
| 目的 | 追求高并发、易扩展、低耦合 | 追求业务连续性、用户识别 |
| 位置 | 协议传输层/网络架构 | 业务应用层 |
| 服务器压力 | 极低(不存连接上下文) | 中等(仅存必要的业务数据) |
-
@CookieValue:从 Cookie 中获取值。
-
@SessionAttribute:从 Session 中获取值。
java
@GetMapping("/set")
public String setData(HttpServletResponse response, HttpSession session) {
// 显式写入一个 Cookie Cookie cookie = new Cookie("user_tag", "AI-Explorer-99");
cookie.setPath("/");
cookie.setMaxAge(3600); // 有效期1小时
response.addCookie(cookie);
// 向 Session 中存入一个属性
session.setAttribute("user_level", "Vip-Member");
return "数据已写入!Cookie: user_tag=AI-Explorer-99, Session: user_level=Vip-Member";
}
//获取cookie - 获取名为user_tag的cookie
@GetMapping("/getCookie")
public String getData(@CookieValue("user_tag") String userTag) {
return "user_tag:" + userTag;
}
//获取session
@GetMapping("/getSession")
public String getSessionData(@SessionAttribute("user_level") String userLevel) {
return "user_level:" + userLevel;
}
由于cookie是存储在客户端(浏览器)中,我们需要把构建好的cookie通过
HttpServletResponse 对象将其添加到响应头中。
session存储在服务端中,需要操作 HttpSession 对象的setAttribute方法,往Session中存储内容
我们先启动服务,存储Cookie和Session,随后通过接口尝试获取

可以看到存储的cookie和session都能正常被拿到.
这里参考cookie是客户端存储,session是服务端存储,不妨我们来重新启动一下服务,来观察还能正常获取cookie和session

4. 响应处理:到底是页面还是数据?
@Controller vs @RestController
我们先在src/main/resources/static/ 这个路径下写一个简单的前端页面index.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
hello cheems , 我是index页面
</body>
</html>
同时在@RestController这个注解的类下添加一个方法,来尝试调用这个接口,为我们返回前端渲染的页面
java
@RestController
@RequestMapping("/request")
public class RequestController {
//返回静态页面
@RequestMapping("/getIndex")
public Object getIndex(){
return "/index.html";
}
}

但是当输入:http://127.0.0.1:8080/request/getIndex 时,只返回了一个字符串,看上去我们的接口是吧其当作String类型给return了。这是因为在 Spring MVC 中,@RestController 的作用相当于 @Controller + @ResponseBody。这意味着该类下所有方法的返回值都会被直接写入 HTTP 响应体中(当作普通字符串),而不会被解析为跳转页面的路径。
那么如何才能正确拿到这个页面呢?这个时候就需要来使用 @Controller了
-
@Controller :定义一个控制器,默认返回视图(静态页面)。
-
@ResponseBody :定义返回的数据格式为非视图(直接返回文本、HTML 片段或 JSON)。
-
@RestController :本质上就是
@Controller + @ResponseBody,适合现在流行的前后端分离模式,直接返回数据给前端渲染。

5. 总结
Spring MVC 的学习本质上就是掌握这些注解的用法。通过这些注解,我们可以轻松完成:
-
建立连接(@RequestMapping)
-
获取请求参数(@RequestParam, @RequestBody, @PathVariable)
-
给出响应(@ResponseBody, @RestController)
下面是一个核心注解总结表
Spring MVC 核心注解功能总结表,仅供参考
| 注解名称 | 主要功能描述 | 常用场景示例 |
|---|---|---|
| @RequestMapping | 路由映射:将用户请求的 URL 绑定到特定的类或方法上 。 | 想象双十一凌晨,你的点击必须精准命中"结算"逻辑 。 |
| @RequestParam | 后端参数重命名:当前端传参 key 与后端变量名不一致时进行手动映射 。 | 页面传的是 time,后端接收变量叫 createtime 。 |
| @RequestBody | 接收 JSON 数据:将 HTTP 请求正文中的 JSON 字符串转为 Java 对象 。 | 前端通过 Ajax 发送了一个包含用户详细信息的 JSON 结构 。 |
| @PathVariable | 获取路径变量:从动态 URL 路径中直接提取参数值 。 | 访问特定资源,如:http://.../user/5 中的 5 就是 ID 。 |
| @RequestPart | 文件上传:用于接收前端通过表单上传的文件数据(MultipartFile) 。 | 用户在个人资料页上传头像图片 cat.jpg 。 |
| @ResponseBody | 返回数据:表示该方法返回的是响应正文数据,而非跳转视图页面 。 | 仅给前端返回一个"操作成功"的字符串或一组 JSON 数据 。 |
| @Controller | 定义控制器:声明类为控制器,默认会将返回值解析为视图(HTML)路径 。 | 访问 /index 时,服务器需要跳转并展示 index.html 页面 。 |
| @RestController | 数据控制器 :是 @Controller 和 @ResponseBody 的组合,默认返回数据 。 |
目前主流的前后端分离开发,后端只负责提供 API 数据接口 。 |
| @CookieValue | 获取 Cookie:从 HTTP 请求头的 Cookie 字段中快速提取特定名称的值 。 | 检查浏览器是否保存了用户的特定偏好设置或令牌 。 |
| @SessionAttribute | 获取 Session:从服务器端的会话(Session)中获取存储的用户信息 。 | 确认当前操作的用户是否已经登录(从 Session 取出 username) 。 |
| @RequestHeader | 获取 Header:从 HTTP 请求报头中获取特定的 Header 信息(如 User-Agent) 。 | 识别用户是用什么浏览器访问的,以便进行兼容性处理 。 |
💡 每日思考题
既然 @RequestMapping 默认支持所有请求方式,而在企业级接口开发中,我们通常会严格区分 GET 和 POST。除了在 @RequestMapping 里手动指定 method 属性外,Spring 还提供了哪些更简洁、语义更明确的注解来替代它?(提示:想想组合注解)
有关SpringMVC的注解就介绍到这里了,如有纰漏还请指出~~