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
用户请求 --> Controller --> Model --> Controller --> View --> 用户界面

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
2
3
4
5
6
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}

使用 @SpringBootApplication ,springBoot会自动注册 DispatcherServletContextLoaderListener 等,无需手动配置。

控制器(Controller)

1. @Controller

作用:

  • 用于标注一个类是控制器组件(Controller),由SpringMVC扫描并注册到容器中,用来接收和处理前端请求。

示例:

1
2
3
4
5
6
7
@Controller
public class UserController {
@RequestMapping("/hello")
public String sayHello() {
return "hello"; // 返回视图名
}
}

视图:常用的视图文件有 .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
2
3
4
5
6
7
8
9
@RequestMapping("/user")	//类控制器前缀
public class UserController {

@RequestMapping("/login") //实际路径为/user/login
public String loginPage() {
return "login";
}
}

常用参数:

  • value:路径
  • method:请求方式(GET 、PUST)
  • params:参数条件
  • headers:请求头条件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Controller
@RequestMapping("/user")
public class UserController {

@RequestMapping(
value = "/login", // 1. 请求路径
method = RequestMethod.POST, // 2. 请求方法:POST
params = {"username", "password"}, // 3. 必须包含这两个请求参数
headers = "Content-Type=application/x-www-form-urlencoded" // 4. 必须包含这个头并且值相等,其他头不做限制
)
public String login(
@RequestParam String username,
@RequestParam String password
) {
// 登录逻辑
System.out.println("用户名:" + username);
System.out.println("密码:" + password);
return "loginSuccess"; // 返回视图名
}
}

接受多种请求方式:

1
@RequestMapping(value = "/example", method = {RequestMethod.GET, RequestMethod.POST})

异常

  1. 有多个RequestMapping 相等时(相等指value,params,headers等参数完全相等)
    • Spring会在启动时,报错 Ambiguous mapping
  2. 如果它们的映射信息有任何差别(即使在运行时某个请求同时满足了两个映射条件),Spring 也会先注册成功,然后在运行时再根据“最具体(narrowest)”原则去选一个最优映射执行——如果仍然无法区分,就抛出运行时 ServletException。同时返回500给客户端。

3. @GetMapping / @PostMapping / @PutMapping / @DeleteMapping

作用:

  • @RequestMapping 的快捷方式,用于简化代码(Spring 4.3+ 推荐使用)。
1
2
3
4
5
6
7
8
9
10
@GetMapping("/user/list")
public String listUsers() {
return "userList";
}

@PostMapping("/user/add")
public String addUser() {
return "success";
}

@GetMapping@PostMapping@PutMapping@DeleteMapping 等复合注解本质上就是带了默认 method@RequestMapping,它们完全继承@RequestMapping 的其它属性:value,params,headers…。

推荐的方法

  • 在你需要使用精细匹配时,一律使用 RequestMapping
  • 在不需要精细匹配时,使用 GetMapping等尽可能简化代码。

4. @RequestParam

作用:

  • 用于获取请求参数(通常是URL查询参数或表单参数)

示例:

1
2
3
4
5
@GetMapping("/search")
public String search(@RequestParam("keyword") String keyword) {
System.out.println("搜索关键词:" + keyword);
return "result";
}

使用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
2
3
4
5
6
@GetMapping("/{year}/{month}/{day}/{filename}/")
public Message returnBlogByPath(
@PathVariable int year,
@PathVariable int month,
@PathVariable int day,
@PathVariable String filename)

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
    10
    public 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
    9
    import 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
2
3
4
5
@GetMapping("/api/user")
@ResponseBody
public User getUser() {
return new User("张三", 18);
}

会自动将java类转化为JSON数据。

8. @RestController

作用:

  • @Controller + @ResponseBody的组合,简化RESTful 风格的API 开发。

示例:

1
2
3
4
5
6
7
8
9
@RestController
@RequestMapping("/api/user")
public class UserRestController {

@GetMapping("/{id}")
public User getUser(@PathVariable int id) {
return new User("张三", 18);
}
}

9. @ModelAttribute

作用:

  • 用于将请求的参数直接绑定到对象
  • 用于在请求处理前设置模型属性

示例:

  • 表单如下:
1
2
3
4
5
6
<form action="/register" method="post">
用户名:<input name="username" /><br>
密码:<input name="password" type="password" /><br>
年龄:<input name="age" /><br>
<input type="submit" value="注册" />
</form>
  • 表单对应数据的类如下:
1
2
3
4
5
6
public class User {
private String username;
private String password;
private Integer age;
// getter/setter 省略
}
  • Controller如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import 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
2
3
4
5
@GetMapping("/hello")
public String hello(Model model) {
model.addAttribute("msg", "Hello, SpringMVC!");
return "hello"; // 返回视图名
}

在hello视图中msg的变量会被替换显示为:Hello,SpringMVC!

在视图中存在,但是未被设置具体value的key不会视图中显示。

ModelMap

org.springframework.ui.ModelMap 是Model的一个实现类,继承自LinkedHashMap,具有Map的全部功能。

示例:

1
2
3
4
5
6
@GetMapping("/hello")
public String hello(ModelMap modelMap) {
modelMap.addAttribute("msg", "Hello, ModelMap!");
// modelMap.put("msg", "Hello, ModelMap!") 也可以
return "hello";
}

ModelAndView

org.springframework.web.servlet.ModelAndView 既可以携带模型数据,也可以指定返回的视图。

示例:

1
2
3
4
5
6
7
@GetMapping("/hello")
public ModelAndView hello() {
ModelAndView mav = new ModelAndView();
mav.addObject("msg", "Hello, ModelAndView!");
mav.setViewName("hello");
return mav;
}

SpringMVC注解
http://blog.ulna520.com/2025/05/16/SpringMVC_20250516_205704/
Veröffentlicht am
May 16, 2025
Urheberrechtshinweis