Spring Boot Web 开发入门:从零搭建到 RESTful API 设计
一、搭建最基础的 Spring Boot 项目
1. 项目结构配置(pom.xml)
使用 Spring Boot 2.7.18(目前最稳定的版本),依赖保持最精简:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
</parent>
<groupId>xdml</groupId>
<artifactId>demo</artifactId>
<version>0.0.1</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
2. 启动类与第一个 Controller
Application.java —— 程序的入口:
package xdml;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
HelloController.java —— 第一个接口,访问根路径返回文字:
package xdml;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/")
public String index() {
return "Spring Boot 运行成功!";
}
}
启动后访问 http://localhost:8080/,看到返回内容即代表项目运行正常。
二、Web 应用的本质
一切 Web 开发,归根结底只做两件事:
处理 HTTP 请求:
- 从 Query String 中提取参数(
?key=value) - 从请求 Body 中读取数据(JSON、表单等)
返回 HTTP 响应:
- Status Code(状态码,如 200、404、500)
- Response Header(响应头)
- Response Body(响应体,可以是 JSON、HTML 等)
三、处理 GET 请求:@RequestParam
GET 请求通过 Query String 传参,格式为 ?param1=value1¶m2=value2,通常用于传递非敏感的查询信息。在 Spring Boot 中使用 @RequestParam 接收:
@RequestMapping("/search")
public String search(@RequestParam("q") String searchKeyword) {
return "你正在搜索:" + searchKeyword;
}
访问 /search?q=Java 即可看到结果。
多参数 + 非必填的完整示例
@RequestMapping("/search")
public String search(
@RequestParam(value = "q", required = false) String searchKeyword,
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
@RequestParam(value = "sort", required = false) String sort
) {
return "搜索关键词:" + searchKeyword + "\n"
+ "当前页码:" + page + "\n"
+ "每页条数:" + size + "\n"
+ "排序方式:" + sort;
}
required = false 表示该参数非必填,defaultValue 为不传时的默认值。
四、幂等性(Idempotent)
在学习 HTTP 方法之前,有必要先理解幂等性这个概念。
幂等:同一请求执行 1 次与执行 N 次,对系统产生的副作用完全相同。简单说,就是重复请求不会搞坏数据。
生活类比
| 操作 | 是否幂等 | 原因 |
|---|---|---|
| 按电梯"关门"键 | ✅ 幂等 | 按多少次都是"关门" |
| 银行转账 | ❌ 不幂等 | 每次点击都会扣款 |
HTTP 方法的幂等性
| 方法 | 幂等 | 说明 |
|---|---|---|
| GET | ✅ | 查询数据,不修改任何状态 |
| PUT | ✅ | 覆盖更新,多次结果一致 |
| DELETE | ✅ | 删除后再删,结果仍是"已删除" |
| POST | ❌ | 重复提交会重复创建数据 |
为什么要关心幂等?
网络超时重试、用户重复点击、消息队列重复投递……这些场景在生产环境中随时发生。如果接口不幂等,就会出现重复下单、重复扣款等严重问题。
查询接口天然幂等,而新增、支付等写操作接口必须手动做幂等控制。
五、RESTful API 设计规范
RESTful 是目前最流行的 API 设计风格,核心思想:
- URL(名词)代表资源,使用复数表示列表,如
/users、/repos - HTTP 动词代表操作:
| HTTP 方法 | 含义 |
|---|---|
| GET | 获取资源 |
| POST | 新建资源 |
| PUT | 更新资源 |
| DELETE | 删除资源 |
路径参数:@PathVariable
RESTful 风格通常将关键参数内嵌在路径中,使用 @PathVariable 接收:
@RestController
@RequestMapping("repos")
public class IssueController {
// DELETE /repos/{owner}/{repo}/issues/{issueNumber}/lock
@DeleteMapping("/{owner}/{repo}/issues/{issueNumber}/lock")
public void unlock(
@PathVariable String owner,
@PathVariable String repo,
@PathVariable String issueNumber) {
System.out.println(owner);
System.out.println(repo);
System.out.println(issueNumber);
}
}
这个例子模拟了 GitHub API 的风格 —— 解锁某个 Issue。
六、处理 POST 请求
POST 请求的参数通常在请求 Body 中,Spring Boot 提供了两种主要方式接收:
| 场景 | Content-Type | 注解 |
|---|---|---|
| 接收 JSON 对象 | application/json | @RequestBody |
| 接收表单参数 | application/x-www-form-urlencoded | @RequestParam |
@RequestBody(绝对主流)
前后端分离架构下,前端(Vue/React)传来的几乎都是 JSON,直接用 @RequestBody 接收一个 Java 对象,Spring Boot 会自动完成 JSON 反序列化:
@PostMapping("/user")
public void addUser(@RequestBody User user) {
// 前端传 JSON,自动映射为 Java 对象
}
💡 开发技巧:可以安装 IDEA 插件 GsonFormat,粘贴一段 JSON 即可一键生成对应的 Java 实体类,极大提升效率。
@RequestParam(处理表单)
适合参数较少、传统表单提交或第三方回调(如微信支付回调)的场景:
@PostMapping("/demo")
public void formDemo(
@RequestParam("aaa") String aaa,
@RequestParam("bbb") Integer bbb) {
System.out.println(aaa);
System.out.println(bbb);
}
如何选择?
- 日常接口开发 → 无脑用
@RequestBody - 老项目表单、第三方回调 → 使用
@RequestParam
七、返回 HTTP 响应
Spring Boot 提供多种方式生成响应,常见的有以下几种:
| 方式 | 说明 |
|---|---|
直接操作 HttpServletResponse | 原始、灵活,适合特殊需求 |
| 直接返回字符串 | 简单粗暴,适合调试 |
| 返回对象自动序列化为 JSON | 最常用 |
| 模板引擎渲染 HTML | 适合服务端渲染,如 Freemarker |
返回 JSON(最常用方式)
在 @RestController 下,直接 return 一个 Java 对象,Spring Boot 会自动将其转换为 JSON:
@RequestMapping("/search")
public Object search(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> result = new HashMap<>();
result.put("result", Arrays.asList("aaa", "bbb", "ccc"));
return result;
}
响应体将自动变为:
{
"result": ["aaa", "bbb", "ccc"]
}
如果想返回 XML?
控制请求头中的 Accept 字段即可,将其设置为 application/xml,并在项目中添加对应的 XML 序列化依赖,Spring Boot 会自动处理格式转换。
总结
| 知识点 | 核心要点 |
|---|---|
| 项目搭建 | spring-boot-starter-web 一个依赖即可启动 |
| GET 参数 | @RequestParam 接收 Query String |
| 路径参数 | @PathVariable 接收 URL 中的变量 |
| POST 参数 | JSON → @RequestBody;表单 → @RequestParam |
| 幂等性 | 查询天然幂等,写操作需手动保证 |
| RESTful | 名词 URL + 动词 HTTP Method |
| 响应 JSON | 返回对象,@RestController 自动序列化 |
Spring Boot 的设计哲学是"约定大于配置",掌握以上基础后,你已经具备了构建标准 RESTful 接口的能力。后续可以进一步学习数据库集成(Spring Data JPA/MyBatis)、全局异常处理、统一响应封装等进阶内容。