Spring Web MVC(1)

一、Spring MVC 是什么?

核心角色 :Spring MVC 是⼀套基于 Servlet 规范 的Web开发框架,像餐厅的标准化管理流程,规定了每个环节的职责。用户发起请求(点餐)时,Spring MVC协调各组件处理并响应结果(上菜)。

二、MVC模式深度解析

类比餐厅模型

角色 职责 对应Spring组件
顾客(用户) 发起请求(点菜) 浏览器用户
服务员(View) 展示菜单并上菜(显示结果) JSP/Thymeleaf模板
前厅经理(Controller) 接收订单并分发给厨房,确保流程顺畅 @Controller注解的类
厨师(Model) 处理菜品制作(数据操作、业务逻辑) Service层、DAO层

代码流程示例

java 复制代码
@RestController
public class OrderController {
    @RequestMapping("/order")
    public String placeOrder(@RequestParam String dish) {
        // Service层处理业务(模拟订单处理)
        String result = kitchenService.cookDish(dish);
        return "您的 " + result + " 已准备好!";
    }
}

访问http://localhost:8080/greet → 显示 Hello, Spring MVC!

访问流程

用户访问 http://localhost:8080/order?dish=牛排 → Controller接收参数 → 调用Service处理 → 返回结果。

代码映射:用户访问URL → Controller接收 → Model处理 → View返回结果。

三、核心注解与请求处理

1. @RequestMapping:路由映射的"菜单本"
核心作用
  • URL路由匹配:将HTTP请求的URL路径映射到指定的控制器方法。
  • 方法类型指定:定义支持的HTTP方法(GET、POST、PUT、DELETE等)。
  • 请求头/参数限制:通过附加条件(如请求头、参数等)细化路由匹配规则。
主要属性
属性 类型 说明
value String[] 指定URL路径(可多个路径映射同一方法)。
method RequestMethod[] 限制请求方法(如RequestMethod.GETRequestMethod.POST)。
params String[] 要求请求必须包含某些参数或参数值(如"name=John")。
headers String[] 要求请求头中必须包含指定内容(如"Content-Type=application/json")。
使用示例
基本路由
java 复制代码
@RestController
@RequestMapping("/api")
public class ApiController {

    // 匹配 GET /api/hello
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String sayHello() {
        return "Hello, Spring!";
    }

    // 匹配 POST /api/user,且要求Content-Type为application/json
    @RequestMapping(
        value = "/user",
        method = RequestMethod.POST,
        headers = "Content-Type=application/json"
    )
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }
}

多路径映射

java 复制代码
// 匹配 GET /api/book 或 /api/books
@RequestMapping(value = {"/book", "/books"}, method = RequestMethod.GET)
public List<Book> listBooks() {
    return bookService.findAll();
}
2.. @RequestParam:处理查询参数

场景 :从URL的问号后获取参数(如 /user?name=John&age=20)。

示例代码

java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {

    // 获取单个(必须有name参数)
    @GetMapping("/detail")
    public String getUserDetail(@RequestParam String name) {
        return "用户名称: " + name;
    }

    // 参数别名、默认值(可无age参数)
    @GetMapping("/age")
    public String getUserAge(
            @RequestParam(value = "userAge", required = false, defaultValue = "18") Integer age) {
        return "用户年龄: " + age;
    }

    // 接收数组参数(多个相同的键)
    @GetMapping("/hobbies")
    public String getHobbies(@RequestParam List<String> hobbies) {
        return "用户爱好: " + hobbies;
    }
}

请求示例

  • 必须参数GET /user/detail?name=John → 返回 用户名称: John
  • 可选参数GET /user/age → 返回 用户年龄: 18(使用默认值)
  • 数组参数GET /user/hobbies?hobbies=编程&hobbies=音乐 → 返回 用户爱好: [编程, 音乐]
3. @PathVariable:获取URL路径参数

场景 :用于RESTful风格URL中标识资源(如 /user/1001 中的用户ID)。

示例代码

java 复制代码
@RestController
@RequestMapping("/product")
public class ProductController {

    // 单一路径参数
    @GetMapping("/{id}")
    public String getProduct(@PathVariable Long id) {
        return "产品ID: " + id;
    }

    // 多路径参数与别名
    @GetMapping("/{category}/{sku}")
    public String getProductByCategoryAndSku(
            @PathVariable("category") String productCategory,
            @PathVariable String sku) {
        return "分类: " + productCategory + ", SKU编码: " + sku;
    }
}
4. @RequestBody:接收JSON请求体

场景:处理POST/PUT请求中的复杂数据(如用户注册、订单提交)。

示例代码

java 复制代码
@RestController
@RequestMapping("/order")
public class OrderController {

    // 接收JSON对象并转为Java对象
    @PostMapping("/create")
    public Order createOrder(@RequestBody Order order) {
        // 假设处理订单保存逻辑
        order.setStatus("已创建");
        return order;
    }
}

// 订单类(模型)
public class Order {
    private Long id;
    private String productName;
    private Integer quantity;
    private String status;
    // 省略Getter/Setter
}

请求示例(Postman)

  • URLPOST /order/create
  • HeadersContent-Type: application/json
  • Body(JSON)
java 复制代码
{
    "productName": "笔记本电脑",
    "quantity": 1
}

响应

java 复制代码
{
    "id": null,
    "productName": "笔记本电脑",
    "quantity": 1,
    "status": "已创建"
}

5 .@RequestPart:文件上传与多部分请求处理

核心作用

文件上传处理 :接收HTTP多部分(multipart/form-data)请求中的文件或其他分块数据。

绑定参数 :将上传的文件或其他表单字段映射到方法参数(如MultipartFile对象)

主要属性

属性 类型 说明
value String 指定表单字段的名称(对应HTML中的name属性)。
required boolean 是否为必传字段(默认为true)。
3. 使用示例
单文件上传
java 复制代码
@PostMapping("/upload")
public String uploadFile(@RequestPart("file") MultipartFile file) {
    String fileName = file.getOriginalFilename();
    try {
        file.transferTo(new File("D:/uploads/" + fileName));
        return "文件上传成功:" + fileName;
    } catch (IOException e) {
        return "文件上传失败:" + e.getMessage();
    }
}

Postman测试

  • 请求方式POST /upload
  • HeadersContent-Type: multipart/form-data
  • Body :选择form-data,设置Key为file(类型为File),上传文件。

多文件上传

java 复制代码
@PostMapping("/upload-multi")
public String uploadFiles(@RequestPart("files") List<MultipartFile> files) {
    StringBuilder result = new StringBuilder("上传成功文件:");
    for (MultipartFile file : files) {
        if (!file.isEmpty()) {
            result.append(file.getOriginalFilename()).append(", ");
        }
    }
    return result.toString();
}

Postman测试

Body :设置多个Key为filesFile字段,选择不同文件。

混合表单参数与文件上传

java 复制代码
@PostMapping("/user-profile")
public String updateProfile(
    @RequestPart("avatar") MultipartFile avatar,
    @RequestPart("username") String username,
    @RequestPart("bio") String bio
) {
    return String.format(
        "用户信息更新:头像=%s, 用户名=%s, 简介=%s",
        avatar.getOriginalFilename(),
        username,
        bio
    );
}

Postman测试

  • Body
    • avatar:上传图片文件。
    • username:填文字(如John)。
    • bio:填文字(如Java开发者

核心区别总结

对比维度 @RequestParam @PathVariable @RequestBody
参数位置 URL查询字符串(?name=John URL路径(/user/{id} 请求体(HTTP Body)
常见数据格式 字符串、基础类型 字符串、基础类型 JSON/XML(复杂对象)
是否必传 默认为是(可设required=false 是(路径必须包含变量) 是(除非允许空Body)
典型应用 过滤条件、分页参数 RESTful资源标识 创建/更新资源(如用户信息)
注解 典型场景 数据格式 常见参数类型
@RequestMapping 定义所有HTTP方法的请求处理入口 无限制(可结合其他注解处理) 无要求(通常结合其他注解)
@RequestPart 处理文件上传或混合表单数据(multipart/form-data 文件、文本字段混合 MultipartFileString

四、常见问题与注意事项

  1. @RequestParam 默认必传

    • 若未传递参数,会抛出 400 Bad Request,可通过设置 required=false 避免。
  2. @PathVariable 路径变量类型

    • URL路径中的变量默认为字符串,Spring会自动转换为基础类型(如Integer、Long)。
  3. @RequestBody 仅支持POST/PUT

    • GET请求无法携带请求体,需使用其他方式传递数据。
  4. 处理多值参数(数组/集合)

    • @RequestParam 可直接绑定到 List<String>,但需重复键名(如 ?hobbies=编程&hobbies=音乐)。
  5. 参数名称匹配

    • @PathVariable 若参数名与路径变量名一致,可省略 value 属性。
  6. @RequestMapping :Spring MVC的路由核心,定义请求的入口和规则。

  7. @RequestPart :处理文件上传和复杂表单字段的专用注解。

  8. 组合使用 :多数情况下,@RequestMapping搭配其他注解(如@RequestParam@RequestBody@RequestPart)实现完整功能。

相关推荐
ChinaRainbowSea3 分钟前
Linux: Centos7 Cannot find a valid baseurl for repo: base/7/x86_64 解决方案
java·linux·运维·服务器·docker·架构
囧囧 O_o4 分钟前
Java 实现 Oracle 的 MONTHS_BETWEEN 函数
java·oracle
去看日出7 分钟前
RabbitMQ消息队列中间件安装部署教程(Windows)-2025最新版详细图文教程(附所需安装包)
java·windows·中间件·消息队列·rabbitmq
计算机-秋大田9 分钟前
基于Spring Boot的宠物健康顾问系统的设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
JouJz16 分钟前
Java虚拟机之垃圾收集(一)
java·开发语言·jvm
uhakadotcom21 分钟前
OpenHands:AI 驱动的软件开发框架
后端·面试·github
源码姑娘29 分钟前
基于DeepSeek的智慧医药系统(源码+部署教程)
java·人工智能·程序人生·毕业设计·springboot·健康医疗·课程设计
morris13134 分钟前
【redis】布隆过滤器的Java实现
java·redis·布隆过滤器
uhakadotcom34 分钟前
FinGPT:金融领域的开源语言模型框架
后端·面试·github
五行星辰1 小时前
Java链接redis
java·开发语言·redis