跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
|注册
博客列表

目录

  1. 1.前置知识
  2. 1.1 Tomcat
  3. 1.2 Servlet
  4. 1.2.1 定义
  5. 1.2.2 API 示范
  6. 1.2.3 生命周期
  7. 2.SpringBoot
  8. 3.Spring Web MVC
  9. 3.1 概述
  10. 3.2 必需工具
  11. 3.3 RequestMapping
  12. 3.4 RequestBody
  13. 3.5 RequestParam
  14. 3.6 PathVariable
  15. 3.7 RequestPart
  16. 3.8 Controller&ResponseBody&RestController
Javajava

Java Spring Web MVC 核心注解与使用指南

介绍 Java Web 开发基础,涵盖 Tomcat 与 Servlet 生命周期及配置。重点讲解 Spring Boot 优势及 Spring Web MVC 核心注解,包括 RequestMapping、RequestBody、RequestParam 等参数绑定方式,以及 PathVariable 和 RequestPart 的使用,帮助开发者理解从 Servlet 到 Spring MVC 的演进与实战应用。

人间失格发布于 2026/4/5更新于 2026/4/131 浏览
Java Spring Web MVC 核心注解与使用指南

1.前置知识

1.1 Tomcat

定义:Tomcat 是一个开源的轻量级 Web(Http) 服务器和 Servlet 容器。它实现了 Java Servlet 等 Java EE 规范的核心功能,常用于部署和运行 Java Web 应用程序。换言之,Tomcat 就是一个严格遵循 Servlet 规范开发出来的、可以独立安装和运行的 Java Web 服务器/Servlet 容器。

核心功能:

  • Servlet 容器:支持 Servlet 的执行,处理 HTTP 请求和响应。
  • Web 服务器:提供静态资源 (如 HTML) 的访问能力,支持基本的 HTTP 服务。

安装与版本对应:

  • tomcat 官网:Apache Tomcat®

目录结构:

  • bin: 存放可执行文件,如 startup.bat
  • conf: 存放配置文件
  • lib: 存放 Tomcat 运行所需的 jar 文件
  • logs: 存储日志文件
  • temp: 存放临时文件,如上传的文件或缓存数据
  • webapps: 默认 web 应用部署目录
  • work: 服务器的工作目录,存放运行时生成的临时文件 (编译文件)

1.2 Servlet

1.2.1 定义

Servlet 是 Java 语言编写的、运行在服务器端的程序,它遵循一套标准的 API 规范 (Tomcat 是这套规范的一个具体实现/容器,并提供了让 Servlet 与前端交互的运行时环境)。

1.2.2 API 示范

创建项目/配置文件:

  1. 在 IDEA 中创建 Maven 项目。
  2. 在 pom.xml 文件中添加 servlet 依赖 (置于 <project> 标签下)。
<dependencies>
    <dependency>
        <groupId>jakarta.servlet</groupId>
        <artifactId>jakarta.servlet-api</artifactId>
        <!--servlet 依赖版本应与 jdk 和 tomcat 的版本相匹配-->
        <version>6.1.0</version>
        provided
    

极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • DJI DroneID 信号解析工具与算法实现
  • AI 量化交易系统构建指南:从数据清洗到实盘执行
  • Jetson Orin NX 16G 配置 AI 服务自动启动:Ollama、llama-server 与 OpenClaw Gateway
  • 鸿蒙电商购物全栈项目:商品浏览与智能推荐
  • 使用 Jekyll 和 Github Pages 搭建静态博客
  • Flutter ml_algo 在鸿蒙系统下的端侧计算适配与重构指南

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

<scope>
</scope>
</dependency>
</dependencies>
  1. 在 main 路径下创建 webapp/Web-INF/web.xml,在 xml 文件中添加以下内容。
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <display-name>Archetype Created Web Application</display-name>
</web-app>
  1. 下载插件:Smart Tomcat(为了方便启动项目)。

API 示例:

import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

//设置访问路径 (url)
@WebServlet("/method")
//继承 HttpServlet 并重写 doGet 和 doPost 方法
public class MethodServlet extends HttpServlet {
    //接收 method=post 的请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        System.out.println("doPost");
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write("doPost");
    }
    //接收 method=put 的请求
    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        System.out.println("doPut");
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write("doPut");
    }
    //接收 method=delete 的请求
    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        System.out.println("doDelete");
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write("doDelete");
    }
}
1.2.3 生命周期

定义:Servlet 生命周期由 Web 容器 (如 Tomcat) 管理,包含加载、初始化、处理请求和销毁四个阶段。每个阶段对应特定的方法调用,开发者可通过重写这些方法实现自定义逻辑。

  1. 类加载:Web 容器通过类加载器加载 Servlet 类 (通常首次请求触发或容器启动时预加载,字节码文件被加载到内存但未实例化)。
  2. 实例化:确认 Servlet 类成功加载后立刻执行,在整个 Web 容器中每种 Servlet 类 (如 HttpServlet) 只会有一个实例化对象。
  3. 初始化:Web 容器调用刚刚创建好的 Servlet 实例的 init(ServletConfig config) 方法,在整个 servlet 实例的生命周期中仅调用一次,主要作用是读取配置和资源加载。若初始化失败,抛出 ServletException,Servlet 不会被加入可用队列。
  4. 处理请求:Web 容器为每个请求创建线程,调用 service(ServletRequest req, ServletResponse res) 方法。service() 方法根据 HTTP 请求类型 (get/post) 调用 doGet() 或 doPost()。
  5. 销毁:Web 容器调用 destroy() 方法,Servlet 实例被标记为垃圾回收。

2.SpringBoot

Servlet 是 Java EE 规范中处理 Web 请求的核心组件,但随着应用复杂度提升,Servlet 的直接使用显得笨重。Spring 框架通过一系列抽象和扩展,简化了企业级应用开发。

我们可以用一个非常形象的比喻来贯穿始终:建造一座房子。

第一阶段:Servlet 时代 - 自己烧砖砌墙

  • 目标:建造一个能遮风挡雨的房子 (一个能处理 HTTP 请求的 Web 应用)。
  • 你的工作状态:
    • 材料:你有最基础的原材料——泥土 (Java 语言) 和水 (JVM)。你需要自己烧制砖块 (编写 Servlet 类)。
    • 工具:只有简单的泥瓦刀 (Servlet API)。
    • 过程:
      1. 你为每一面墙、每一扇门都亲手烧制一块特定的砖 (编写 LoginServlet, UserServlet, OrderServlet)。
      2. 你亲自规划每块砖的位置 (在 web.xml 中配置大量的 <servlet> 和 <servlet-mapping>)。
      3. 你亲自搅拌水泥,一块一块地砌墙 (在每个 Servlet 的 doGet/doPost 方法中手动解析参数、处理业务、组装 HTML)。
  • 核心特点:
    • 高度灵活:你可以造出任何形状的砖。
    • 极其繁琐:大量重复性劳动 (每个 Servlet 都有获取参数、关闭连接等样板代码)。
    • 难以维护:砖块之间紧密耦合 (对象依赖硬编码),想换一扇窗 (修改功能) 可能会牵动整面墙。
    • 依赖外部:房子建在别人的地上 (需要将 war 包部署到外部的 Tomcat 服务器)。
  • 总结:Servlet 提供了 Web 开发的基础能力,但开发效率极低,代码冗余且难以维护。

第二阶段:Spring 时代 - 使用预制件和设计图纸

  • 目标:用更高效、更标准化的方式建造一个结构更好、更易扩展的房子。
  • 你的工作状态:
    • 材料:你不再烧砖,而是使用工厂提供的标准化预制件 (Spring Bean,如 @Controller, @Service)。
    • 核心创新:你聘请了一位神奇的管家 (IoC 容器)。你不再亲自'砌砖'(用 new 实例化对象),只需告诉管家你需要什么 (用 @Autowired 声明依赖)。管家会自动把预制件 (Bean) 按照图纸 (配置) 组装好,送到你手上 (依赖注入 DI)。
    • 过程:
      1. 一个总大门 (DispatcherServlet):房子只有一个入口,所有访客 (请求) 都先到这里。
      2. 管家调度:总大门处的接待员 (DispatcherServlet) 根据访客需求,呼叫房子里对应的专业房间 (@Controller 中的方法) 来接待。
      3. 开发者只需专注于房间内的专业服务 (业务逻辑),而不用关心访客是怎么进来的。
  • 核心特点:
    • 解耦:预制件之间是松耦合的,易于更换和测试。
    • 专业化:AOP(面向切面编程) 可以像'装修队'一样,非侵入式地为所有房间统一安装中央空调(日志、安全、事务)。
    • 效率提升:避免了大量重复劳动,结构清晰。
    • 配置复杂:绘制详细的'组装图纸'(配置 Spring) 本身成了一项复杂的工作。
  • 总结:Spring 框架通过 IoC/DI 和 AOP 等理念,解决了代码耦合和重复劳动问题,但引入了显著的配置复杂度。

Spring Boot 1.0.0正式发布于 2014 年 4 月 1 日,标志着该框架的首次稳定版本发布。SpringBoot 基于 Spring Framework 4 进行设计,显著减少了开发者的配置工作量,彻底消除了 Spring 的配置地狱。

  • 约定大于配置:约定了默认配置。
  • Start 机制:是一种依赖管理机制,每个 Starter 包含特定功能所需的依赖库和自动配置类,开发者只需引入对应 Starter 即可快速启用功能模块。
  • 嵌入式容器:内置了 Tomcat 等嵌入式容器,无需部署 war 文件到外部容器,直接运行即可启动应用。

3.Spring Web MVC

3.1 概述

官方描述:Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,并从一开始就在 Spring 框架中。正式名称'Spring Web MVC',来自其源模块的名称 (spring-webmvc),但它通常被称为'Spring MVC'。

MVC 的起源与发展:MVC(Model-View-Controller) 模式最初由挪威计算机科学家 Trygve Reenskaug 于 1978 年在施乐帕克研究中心 (Xerox PARC) 提出,目的是为 Smalltalk 编程语言设计用户界面。其核心思想是将应用程序的逻辑分为三个独立组件:

  • Model:处理数据逻辑和业务规则。
  • View:负责数据展示和用户界面。
  • Controller:接收用户输入并协调 Model 与 View 的交互。

Spring MVC 与 MVC 的关系:Spring MVC 是 MVC 模式在 Spring 框架中的具体化,同时扩展了传统 MVC 的功能以适应现代 Web 开发需求。

3.2 必需工具

Postman:主要用于 API 的开发和测试。它提供了一个用户友好的界面,支持发送 HTTP 请求、管理请求历史、自动化测试以及团队协作。 下载地址:Download Postman

Fiddler:是一个网络调试代理工具,主要用于监控和分析 HTTP/HTTPS 流量。它可以捕获设备与服务器之间的所有请求和响应,支持修改请求、重放请求以及性能分析。 下载地址:Fiddler - Download

3.3 RequestMapping

作用:是 Spring MVC 中最核心、最基础的注解之一,用于将 HTTP 请求映射到具体的方法上。 注解级别:类 + 方法。 作为类注解:可以为整个类提供一个统一的 url 前缀 (可有可无)。 作为方法注解:指定该方法负责处理哪个 url 的请求 (强制要求)。

@RequestMapping("/HelloController")
//@RestController 声明该类是一个 Spring MVC 控制器
@RestController
public class HelloController {
    //0.不接收参数
    //作为 方法注解 时,@RequestMapping(value = "/hello",method = RequestMethod.GET)等同于@GetMapping(value = "/hello")
    //设置返回的响应是 json 格式,produces = "application/json"
    @RequestMapping(value = "/hello", method = RequestMethod.GET, produces = "application/json")
    public String hello() {
        return "{\"Hello\" : World}";
    }
    //1.一个参数
    @RequestMapping("/receiveAge1")
    //不传参或者传递的参数名不匹配时默认为 null
    public String receiveAge1(Integer age) {
        return "接收到参数 age:" + age;
    }
    @RequestMapping("/receiveAge2")
    //不传参或者传递的参数名不匹配时尝试设置为 null,但 int 无法被设置为 null,所以抛出 IllegalStateException
    public String receiveAge2(int age) {
        return "接收到参数 age:" + age;
    }
    //2.接收数组
    @RequestMapping("/receiveArray")
    public String receiveArray(String[] array) {
        return "接收到参数 array:" + Arrays.toString(array);
    }
    //3.接收对象,需要保证传递的参数名称和数量与 Java 对象保持一致
    @RequestMapping("/receivePerson")
    public String receivePerson(Person person) {
        return "接收到参数 person:" + person;
    }
}

3.4 RequestBody

作用:将 HTTP 请求体中的 json 数据绑定到 Java 对象 (方法注解)。 注解级别:方法。

@RequestMapping("/receivePerson")
//@RequestBody 接收 JSON 格式的数据
public String receivePerson(@RequestBody Person person) {
    return "接收到参数 person:" + person;
}

3.5 RequestParam

作用:是 Spring MVC 框架中从 HTTP 请求中提取参数/查询字符串的注解,主要用于将请求参数绑定到控制器方法的参数上。 注解级别:方法。

@RequestMapping("/receiveRename")
//@RequestParam 将 url 中 key=name 的查询字符串绑定到控制器的 userName 参数上
//required = false 设置该参数为非必传 (默认为 true,必传)
public String receiveRename(@RequestParam(value = "name", required = false) String userName) {
    return "接收到参数 name:" + userName;
}

注意:需要接收多个同名参数时 (如 param=value1&param=value2),直接绑定到 List 类型需通过该注解明确声明。

@RequestMapping("/receiveList1")
public String receiveList1(ArrayList<String> list) {
    //返回的 list 为空
    return "接收到参数 list:" + list;
}

(1) 在 Spring MVC 中,参数绑定机制对集合类型和数组类型的处理存在差异。 (2) 使用 ArrayList< String > 作为方法参数时,必须显式添加 @RequestParam 注解,原因如下:

  • 默认绑定规则:Spring 默认将单个请求参数的值绑定到简单类型 (如 String、int) 或单个对象。对于集合类型,框架无法自动推断是否需要将多个同名参数合并为集合。
  • 需要明确指示:@RequestParam 注解会告知 Spring 将同名请求参数的值收集到一个集合中。 (3) 数组 (如 String[]) 无需 @RequestParam 注解即可正确接收,原因如下:
  • 内置支持:Spring 对数组类型有原生支持,能自动将多个同名请求参数值绑定到数组。这是框架的默认行为,无需额外配置。
@RequestMapping("/receiveList2")
public String receiveList2(@RequestParam(required = false) ArrayList<String> list) {
    //正确返回
    return "接收到参数 list:" + list;
}
@RequestMapping("/receiveList3")
public String receiveList3(List<String> list) {
    //报错
    return "接收到参数 list:" + list;
}

后端报错:java.lang.IllegalStateException: No primary or single unique constructor found for interface java.util.List。receiveList3 方法使用 List< String > 接口类型而非具体实现类。Spring 虽然支持接口类型参数绑定,但需要满足特定条件:必须配合 @RequestParam 注解使用,不能直接使用未注解的接口类型参数。

报错根本原因:Spring 尝试实例化 List 接口失败 (接口不可实例化)。

3.6 PathVariable

作用:用于从 URL 路径中提取变量值并绑定到方法的参数上。 注解级别:方法。

@RequestMapping("/receivePath/{article}/{blog}")
//required = false 设置该参数为非必传 (默认为 true,必传)
public String receivePath(@PathVariable(value = "article", required = false) Integer title, @PathVariable(value = "blog", required = false) String content) {
    return "接收到参数 article:" + title + " blog:" + content;
}

3.7 RequestPart

作用:用于处理 HTTP 请求中的 multipart/form-data 类型数据,通常用于文件上传或同时上传文件和其他表单字段的场景。 注解级别:方法。

@RequestMapping("/receiveFile")
public String receiveFile(@RequestPart(value = "file", required = false) MultipartFile imgFile, @RequestParam(value = "userName", required = false) String name) {
    //返回原始的文件名
    return "用户:" + name + ",接收到文件:" + imgFile.getOriginalFilename();
}

3.8 Controller&ResponseBody&RestController

Controller

  • 作用:是 Spring MVC 中的核心注解,用于标记一个类作为 Web 请求的处理器 (声明一个类是一个 Spring MVC 控制器),负责处理 HTTP 请求并返回视图。
  • 注解级别:类。

ResponseBody

  • 作用:指示方法返回值应直接写入 HTTP 响应体,而非通过视图解析器渲染。
  • 注解级别:类 + 方法。
@RequestMapping("/ControllerResponse")
@Controller
public class ControllerResponse {
    //返回视图
    @RequestMapping("/HTMLView")
    public String HTMLView() {
        return "/show.html";
    }
    //返回数据
    @ResponseBody
    @RequestMapping("/HTMLData")
    public String HTMLData() {
        return "/show.html";
    }
}

RestController

  • 作用:是 Spring MVC 中的一个组合注解,它结合了 @Controller 和 @ResponseBody 的功能,标记的类所有方法返回值默认直接作为 HTTP 响应体 (JSON/XML 等格式),无需额外视图渲染。
  • 注解级别:类。
人工智能发展历程与现状分析
  • 昇腾平台 Llama-2-7b 大模型深度测评与部署
  • Fish-Speech 1.5 语音合成 WebUI 搭建与使用指南
  • LLaMA-Factory 命令行工具 llamafactory-cli 使用指南
  • Stable Diffusion API 本地部署与实战调用指南
  • LLaMA-Factory 大模型微调实战:Qwen3 + LoRA
  • FPGA 嵌入式块存储器 RAM:原理与实现指南
  • 基于视觉语言动作的竞速无人机自主导航 RaceVLA 架构解析
  • Notepad++ 直连 SAP SE80 提升 BSP/WebClient UI 视图维护效率
  • VSCode Copilot 无法连接网络问题解决方案
  • AI 与 Apache ECharts 结合生成专业数据可视化图表
  • GeoAI 快速上手:地理空间 AI 分析指南
  • 海尔智能家居集成指南:设备统一管理
  • OpenClaw 深度解析:AI 智能体平台的架构与演进