SpringMVC注解
坚强不是面对悲伤不流一滴泪,而是擦干眼泪后微笑着面对以后的生活。
——《风之谷》
MVC 模式原理(Model-View-Controller)
MVC模式(Model-View-Controller,模型-视图-控制器) 是一种软件架构模式,被广泛用于Web开发和桌面应用开发中。它通过将应用程序分为三部分,使得代码结构清晰,易于维护和扩展。
MVC 的三大核心组成
1. Model(模型)
- 定义 :负责应用程序的数据和业务逻辑。
- 职责 :管理数据、规则、逻辑和功能。例如:数据库操作、数据校验、业务处理。
- 示例 :Java Bean、POJO、数据库实体类、业务逻辑类。
2. View(视图)
- 定义 :负责数据的展示(UI 层)。
- 职责 :将 Model 的数据以用户友好的形式展示出来,不包含业务逻辑。
- 示例 :网页页面(HTML、JSP、Thymeleaf)、App 界面、前端框架页面(Vue/React)。
3. Controller(控制)
- 定义 :负责接收用户请求并调用相应的业务逻辑,返回结果给视图。
- 职责 :协调 Model 和 View 之间的交互,处理用户输入。
- 示例 :Spring MVC 的 Controller、Servlet、Action 类。
MVC的工作流程
1 |
|
SpringMVC
SpringMVC是MVC架构在JAVA语言中的实际应用。SpringMVC中的核心组件由MVC理论中的3层扩充为7大核心组件。每个组件都是为了实现MVC架构而设计。
组件 | 说明 |
---|---|
DispatcherServlet |
前端控制器,负责接收请求并协调各个组件完成请求处理 |
HandlerMapping |
处理器映射器,根据请求URL查找对应的Controller方法 |
HandlerAdapter |
处理器适配器,调用Controller的方法执行 |
Controller |
处理器,业务逻辑处理单元 |
ModelAndView |
Controller返回的数据和视图名 |
ViewResolver |
视图解析器,根据视图名找到具体的视图 |
View |
视图,用于渲染页面(如 JSP、Thymeleaf) |
SpringMVC请求处理按照组件从上到下,完成调用Controller,执行Model,返回View的整个流程。
前后端分离架构
前后端分离架构(Architectural Pattern)
- 前端(Vue3):负责界面展示、用户交互、路由控制
- 后端(Spring Boot):负责业务逻辑处理、数据库操作、提供 API(通常是 RESTful)
✅ 优点:前后解耦、并行开发、跨平台、灵活性高
现在常用的前后端分离的设计模式(Frontend-Backend Separation Architecture)中,传统后端的MVC架构中的View被前端取代了——-SpringBoot只负责返回JSON数据(API),视图渲染全部由Vue等前端框架完成。
RESTful API架构风格
REST 软件架构
REST把系统中的所有对象都抽象成资源,每个资源用URL唯一标识,并通过HTTP方法进行操作。
1. 资源
资源是系统的对象,比如用户、商品、订单等。
- 用户资源:
/users
- 单个用户:
/users/123
- 某个用户的订单:
/user/123/orders
2. 标准HTTP方法
HTTP 方法 | 含义 | 说明 |
---|---|---|
GET | 查询 | 获取资源(不会改变数据) |
POST | 创建 | 创建一个新的资源 |
PUT | 更新 | 更新资源的全部内容 |
PATCH | 局部更新 | 更新资源的部分内容 |
DELETE | 删除 | 删除资源 |
3. URL要具有语义化
非REST:/getUserById?id=123
REST:GET /users/123
✅ 示例:用户管理的 RESTful API
操作 | URL | 方法 | 描述 |
---|---|---|---|
获取用户列表 | /users |
GET | 查询所有用户 |
获取指定用户 | /users/123 |
GET | 查询 id 为 123 的用户 |
创建新用户 | /users |
POST | 提交用户数据创建新用户 |
更新用户 | /users/123 |
PUT | 替换 id 为 123 的用户 |
删除用户 | /users/123 |
DELETE | 删除用户 |
使用SpringMVC
如果通过SpringBoot启动一个Spring项目,大多数情况下我们无需额外配置SpringMVC,也不需要编写web.xml配置文件。
1 |
|
使用 @SpringBootApplication
,springBoot会自动注册 DispatcherServlet
、ContextLoaderListener
等,无需手动配置。
控制器(Controller)
1. @Controller
作用:
- 用于标注一个类是控制器组件(Controller),由SpringMVC扫描并注册到容器中,用来接收和处理前端请求。
示例:
1 |
|
视图:常用的视图文件有
.html
,在SpringBoot中存储路径为:resources/templates/
,当你返回hello
时,实际会将hello.html返回。注:如果以HTML作为视图,需要在pom.xml中添加依赖:
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2. @RequestMapping
作用:
- 用于定义请求路径的映射,可用在类或方法上,支持GET、POST等请求方式的映射。
示例:
1 |
|
常用参数:
- value:路径
- method:请求方式(GET 、PUST)
- params:参数条件
- headers:请求头条件
1 |
|
接受多种请求方式:
1 |
|
异常
- 有多个RequestMapping 相等时(相等指value,params,headers等参数完全相等)
- Spring会在启动时,报错
Ambiguous mapping
- Spring会在启动时,报错
- 如果它们的映射信息有任何差别(即使在运行时某个请求同时满足了两个映射条件),Spring 也会先注册成功,然后在运行时再根据“最具体(narrowest)”原则去选一个最优映射执行——如果仍然无法区分,就抛出运行时
ServletException
。同时返回500给客户端。
3. @GetMapping
/ @PostMapping
/ @PutMapping
/ @DeleteMapping
作用:
- 是
@RequestMapping
的快捷方式,用于简化代码(Spring 4.3+ 推荐使用)。
1 |
|
@GetMapping
、@PostMapping
、@PutMapping
、@DeleteMapping
等复合注解本质上就是带了默认 method
的 @RequestMapping
,它们完全继承了 @RequestMapping
的其它属性:value,params,headers…。
推荐的方法:
- 在你需要使用精细匹配时,一律使用
RequestMapping
。 - 在不需要精细匹配时,使用
GetMapping
等尽可能简化代码。
4. @RequestParam
作用:
- 用于获取请求参数(通常是URL查询参数或表单参数)
示例:
1 |
|
使用Get请求时,传参附在路径后面如:/search?keyword=ulna
POST请求时,@RequestParam 适用于接收表单提交(application/x-www-form-urlencoded)或URL查询,而不是json请求体。
常用参数:
value
:String,请求参数名称,将前端请求参数名绑定到方法参数。required
:boolean,是否必须有该参数,默认为true
,缺少参数时会返回400错误defaultValue
:String,默认值,若请求未带参数则用此值,设置后required
自动为false
。
在前端请求参数名和方法参数名称相同时,可以省略value参数
简化的直接写为
@RequestParam String keyword
有时你需要手动开启
-parameters
编译参数
5. @PathVariable
作用:
- 用于获取URL路径中的变量(RESTful 风格)
示例:
1 |
|
6. @RequestBody
作用:
- 将请求体中的JSON数据绑定到Java对象(常用于POST请求)
示例:
请求体:
1
2
3
4
5
6
7
8{
"username": "Alice",
"age": 25,
"address": {
"city": "Shanghai",
"zip": "200000"
}
}对应Java实体类
1
2
3
4
5
6
7
8
9
10public class User {
private String username;
private int age;
private Address address;
}
public class Address {
private String city;
private String zip;
}Controller实例:
1
2
3
4
5
6
7
8
9import org.springframework.web.bind.annotation.*;
@RestController
public class UserController {
@PostMapping("/addUser")
public String addUser(@RequestBody User user) {
return "用户:" + user.getUsername() + ",年龄:" + user.getAge();
}
}
7. @ResponseBody
作用:
- 将返回值直接写入HTTP响应体(通常用于JSON数据结构),而不是视图名。
1 |
|
会自动将java类转化为JSON数据。
8. @RestController
作用:
@Controller
+@ResponseBody
的组合,简化RESTful 风格的API 开发。
示例:
1 |
|
9. @ModelAttribute
作用:
- 用于将请求的参数直接绑定到对象
- 用于在请求处理前设置模型属性
示例:
- 表单如下:
1 |
|
- 表单对应数据的类如下:
1 |
|
Controller如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@Controller
public class RegisterController {
// 预置应用名,每个页面都能访问到
@ModelAttribute
public void addCommonInfo(Model model) {
model.addAttribute("appName", "SpringMVC Demo 应用");
}
// 处理注册页面表单提交,自动把表单参数封装到 User 对象
@PostMapping("/register")
public String register(@ModelAttribute User user, Model model) {
// 这里 user 会自动绑定表单参数
// 可进行保存、校验等操作
model.addAttribute("msg", "注册成功,欢迎:" + user.getUsername());
return "result"; // 跳转到 result 视图页面
}
}
前端提交表单后,因为 @ModelAttribute
注解,Spring会自动生成一个新的User对象,并将参数自动绑定进去。
10. Model
/ModelMap
/ModelAndView
作用:
- 向视图传递数据。
Model
org.springframework.ui.Model
是一个接口,SpringMVC推荐使用的模型数据传送方式。
示例:
1 |
|
在hello视图中msg的变量会被替换显示为:Hello,SpringMVC!
在视图中存在,但是未被设置具体value的key不会视图中显示。
ModelMap
org.springframework.ui.ModelMap
是Model的一个实现类,继承自LinkedHashMap,具有Map的全部功能。
示例:
1 |
|
ModelAndView
org.springframework.web.servlet.ModelAndView
既可以携带模型数据,也可以指定返回的视图。
示例:
1 |
|