跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Java 基础 (1) —— Spring Web MVC 入门

介绍 Java Web 开发基础,涵盖 Tomcat 服务器与 Servlet 生命周期。重点讲解 Spring Boot 特性及 Spring Web MVC 核心注解,包括 RequestMapping、RequestBody、RequestParam、PathVariable 等参数绑定方式,以及 Controller 与 ResponseBody 的区别。通过对比 Servlet 原生开发与 Spring 框架的差异,帮助开发者理解 MVC 模式在现代 Web 应用中的应用。

DataScient发布于 2026/4/6更新于 2026/5/2024 浏览
Java 基础 (1) —— 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 服务。

目录结构:

  • 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></project> 标签下)。
<dependencies>
    <dependency>
        <groupId>jakarta.servlet</groupId>
        <artifactId>jakarta.servlet-api</artifactId>
        <!--servlet 依赖版本应与 jdk 和 tomcat 的版本相匹配-->
        <version>6.1.0</version>
        <scope>provided</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>

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 请求、管理请求历史、自动化测试以及团队协作。
  • Fiddler:是一个网络调试代理工具,主要用于监控和分析 HTTP/HTTPS 流量。它可以捕获设备与服务器之间的所有请求和响应,支持修改请求、重放请求以及性能分析。

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 等格式),无需额外视图渲染。
    • 注解级别:类。

目录

  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
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 从Python到Java:多语言SDK开发指南
  • Vue 实例劫持突破 Web 编辑器粘贴限制
  • 基于 STM32 的智能水质检测系统
  • LLama-Factory 微调实战:如何打造个性化 AI 角色
  • SpringMVC 企业级开发实战:制作简单小网页
  • OpenCLaw Web UI 访问报错 Not Found 问题排查与修复
  • Python 开发中需要摒弃的 18 个坏习惯
  • 数据结构:链表详解与节点链接原理
  • 数据处理:大模型训练的关键环节与实践
  • 利用无监督学习为大语言模型实现信息记忆与微调
  • 时序数据库选型指南:Apache IoTDB技术解析
  • Python 基础介绍与 12 个核心开发库详解
  • OpenAI COO 访谈:大模型时代企业如何落地应用
  • 三种经典Python量化交易策略详解
  • FPGA 自学笔记:VIVADO RAM IP 核配置与使用
  • 前端路由权限拦截:3 种方案与常见坑点
  • AI 工具在 Java 毕业论文写作中的应用与优化指南
  • 30 道高频 JavaScript 手写实现汇总
  • 职场经验谈:若无必要离职原因,建议谨慎跳槽
  • Linux.do(现名 Pandora)为何成为国内 AI 开发者首选社区

相关免费在线工具

  • 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