前置知识
Tomcat
Tomcat 是一个开源的轻量级 Web 服务器和 Servlet 容器,实现了 Java EE 规范的核心功能。简单来说,它是一个严格遵循 Servlet 规范、可独立运行的 Java Web 服务器。
核心功能:
- Servlet 容器:支持 Servlet 执行,处理 HTTP 请求和响应。
- Web 服务器:提供静态资源访问能力,支持基本 HTTP 服务。
目录结构简介:
bin:存放可执行文件(如 startup.bat)。conf:配置文件目录。lib:运行所需的 jar 包。logs:日志文件。temp:临时文件(如上传缓存)。webapps:默认应用部署目录。work:运行时生成的临时编译文件。
Servlet
定义
Servlet 是运行在服务器端的 Java 程序,遵循标准 API 规范。Tomcat 作为容器提供了让 Servlet 与前端交互的运行时环境。
基础配置示例
创建 Maven 项目后,需在 pom.xml 中添加依赖。注意版本需与 JDK 及 Tomcat 匹配:
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
在 main/webapp/WEB-INF 下创建 web.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>
生命周期
Servlet 的生命周期由 Web 容器管理,包含加载、初始化、处理请求和销毁四个阶段。
- 类加载:容器通过类加载器加载 Servlet 类,通常首次请求触发或启动时预加载。
- 实例化:确认加载成功后立即执行,容器中每种 Servlet 类只有一个实例对象。
- 初始化:调用
init(ServletConfig config)方法,仅调用一次,用于读取配置和资源加载。若失败抛出ServletException。 - 处理请求:为每个请求创建线程,调用
service()方法,根据 HTTP 类型分发到doGet或doPost。 - 销毁:容器调用
destroy()方法,标记实例供垃圾回收。
Spring Boot
Servlet 虽灵活但开发繁琐,大量重复代码导致维护困难。Spring 框架通过抽象简化了企业级开发。
我们可以用建造房子来比喻这个过程:
第一阶段:Servlet 时代 - 自己烧砖砌墙
- 目标:建造能遮风挡雨的房子(Web 应用)。
- 状态:材料只有泥土和水,需要亲手烧制砖块(编写 Servlet),规划每块砖的位置(web.xml 配置),手动搅拌水泥(处理业务逻辑)。
- 特点:高度灵活但极其繁琐,耦合度高,依赖外部容器。
第二阶段:Spring 时代 - 使用预制件和设计图纸
- 创新:聘请管家(IoC 容器),不再亲自'砌砖'(new 对象),只需声明依赖(@Autowired)。管家自动组装预制件(Bean)。
- 流程:总大门(DispatcherServlet)统一接待访客,调度对应房间(Controller)处理。
- 特点:解耦、专业化(AOP 切面)、效率高,但配置相对复杂。
Spring Boot 在此基础上进一步演进,发布于 2014 年。它基于 Spring Framework 4,显著减少配置工作量。
- 约定大于配置:内置默认配置。
- Start 机制:依赖管理机制,引入 Starter 即可启用功能模块。
- 嵌入式容器:内置 Tomcat,无需部署 war 包,直接运行启动。
Spring Web MVC
概述
Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,正式名称源自源模块 spring-webmvc。MVC 模式将应用分为 Model(数据)、View(展示)和 Controller(交互),Spring MVC 则是这一模式在 Spring 中的具体化与扩展。
必需工具
开发过程中常用 Postman 进行 API 测试,或使用 Fiddler 监控分析 HTTP/HTTPS 流量。这些工具能帮助快速验证接口逻辑。
RequestMapping
这是最核心的注解之一,用于将 HTTP 请求映射到具体方法。
- 类注解:提供统一的 URL 前缀。
- 方法注解:指定该方法处理的 URL 路径。
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/method")
public class MethodServlet extends HttpServlet {
@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");
}
}
在 Spring MVC 中,我们更常使用 @RestController 配合 @RequestMapping:
@RequestMapping("/HelloController")
@RestController
public class HelloController {
// GET 请求,返回 JSON 格式
@RequestMapping(value = "/hello", method = RequestMethod.GET, produces = "application/json")
public String hello() {
return "{\"Hello\" : World}";
}
// 接收单个参数,不传参默认为 null
@RequestMapping("/receiveAge1")
public String receiveAge1(Integer age) {
return "接收到参数 age:" + age;
}
// 接收数组
@RequestMapping("/receiveArray")
public String receiveArray(String[] array) {
return "接收到参数 array:" + Arrays.toString(array);
}
// 接收对象,参数名需保持一致
@RequestMapping("/receivePerson")
public String receivePerson(Person person) {
return "接收到参数 person:" + person;
}
}
RequestBody
用于将 HTTP 请求体中的 JSON 数据绑定到 Java 对象。
@RequestMapping("/receivePerson")
public String receivePerson(@RequestBody Person person) {
return "接收到参数 person:" + person;
}
RequestParam
从 HTTP 请求中提取参数或查询字符串,主要用于绑定控制器方法的参数。
@RequestMapping("/receiveRename")
public String receiveRename(@RequestParam(value = "name", required = false) String userName) {
return "接收到参数 name:" + userName;
}
注意:接收多个同名参数时,集合类型处理有差异。
- ArrayList:必须显式添加
@RequestParam注解,否则 Spring 无法推断是否合并参数。 - 数组:原生支持,无需额外注解。
- List 接口:直接使用会报错,因为接口不可实例化,需配合
@RequestParam或改用具体实现类。
@RequestMapping("/receiveList1")
public String receiveList1(ArrayList<String> list) {
// 未加注解,list 为空
return "接收到参数 list:" + list;
}
@RequestMapping("/receiveList2")
public String receiveList2(@RequestParam(required = false) ArrayList<String> list) {
// 正确返回
return "接收到参数 list:" + list;
}
PathVariable
用于从 URL 路径中提取变量值并绑定到方法参数。
@RequestMapping("/receivePath/{article}/{blog}")
public String receivePath(
@PathVariable(value = "article", required = false) Integer title,
@PathVariable(value = "blog", required = false) String content
) {
return "接收到参数 article:" + title + " blog:" + content;
}
RequestPart
处理 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();
}
Controller & ResponseBody & RestController
- @Controller:标记类为 Web 请求处理器,返回值通常为视图名称。
- @ResponseBody:指示方法返回值直接写入 HTTP 响应体,而非渲染视图。
- @RestController:组合注解,等同于
@Controller+@ResponseBody,所有方法返回值默认作为响应体(JSON/XML),适合 RESTful API 开发。
@Controller
public class ControllerResponse {
@RequestMapping("/HTMLView")
public String HTMLView() {
return "/show.html";
}
@RequestMapping("/HTMLData")
@ResponseBody
public String HTMLData() {
return "/show.html";
}
}
掌握这些核心注解与机制,是理解 Spring Web MVC 的关键。实际开发中,建议优先使用 @RestController 构建 API,并根据场景选择合适的参数绑定方式。


