《Spring Boot 第一周:从0到第一个REST API》

📅 2026/6/30 11:18:25
《Spring Boot 第一周:从0到第一个REST API》
前言作为一名有着10年前端经验的开发者我决定拓展自己的技术栈学习 Java 后端开发。本文记录了我在第一周内从零开始搭建 Spring Boot 项目、理解核心概念并成功写出第一个 REST API 的全过程。希望能给同样从零开始的朋友一些参考。一、环境准备1.1 安装 JDK我安装了 JDK 25虽然计划是 JDK 17但高版本完全向下兼容。验证安装java -version输出类似:1.2 安装 IntelliJ IDEA下载并安装了 IntelliJ IDEA Ultimate社区版也完全够用。安装后首次启动选择“免费试用 30 天”即可。1.3 了解 MavenMaven 是 Java 世界的“依赖管理器 构建工具”类似于前端的 npm webpack。它通过pom.xml文件管理项目依赖和构建流程。二、创建第一个 Spring Boot 项目2.1 使用 Spring Initializr在 IDEA 中点击New Project→ 选择Spring Initializr配置如下配置项值Namehello-worldLanguageJavaTypeMavenJDK21与本地 JDK 25 兼容Java21如本电脑2.2 添加依赖在依赖选择界面勾选Spring Web用于构建 REST API。点击Create完成项目创建。2.3 首次运行找到主类 Backend1Application.java点击绿色三角形运行。控制台输出Tomcat started on port(s): 8080 (http) Started HelloWorldApplication in 2.345 seconds浏览器访问http://localhost:8080看到 Whitelabel Error Page404—— 这实际上是成功标志说明服务器已启动只是还没有写任何接口。三、解决常见问题3.1 端口被占用如果启动时报Port 8080 was already in use可以在application.properties中修改端口server.port8085四、理解核心注解4.1 RestController—— 类级别的“控制器印章”作用​ 标记一个类是“控制器”专门处理 HTTP 请求并直接把返回值比如字符串、JSON写回给浏览器不经过视图模板。类比​ 就像在 Vue 里给一个组件加上Component装饰器告诉框架“这是我的一块积木”。4.2 GetMapping—— 方法级别的“GET 请求路由”作用​ 标记一个方法当浏览器发送GET 请求​ 到指定的 URL 时就执行这个方法。例子GetMapping(/hello) public String sayHello() { return 你好; }访问http://localhost:8085/hello就会触发这个方法。特点​ 它是RequestMapping(method RequestMethod.GET)的缩写专门处理 GET 请求。4.3 RequestMapping作用​ 既可以放在类上也可以放在方法上用来指定 URL 路径和请求方法GET、POST、PUT、DELETE 等。用法一放在类上给整个控制器加一个公共前缀RestController RequestMapping(/api) // 这个类里所有方法的 URL 都以 /api 开头 public class BookController { GetMapping(/books) // 实际路径是 /api/books public ListBook getAllBooks() { ... } GetMapping(/books/{id}) // 实际路径是 /api/books/{id} public Book getBookById(PathVariable Long id) { ... } }等价于PutMapping(/books/{id})。这样做的好处是当你有多个接口都归属同一模块比如书籍相关统一加/api前缀代码更整洁也方便后期统一调整路径。用法二放在方法上等同于GetMapping或PostMappingRequestMapping(value /books, method RequestMethod.GET) // 等价于 GetMapping(/books) RequestMapping(value /books, method RequestMethod.POST) // 等价于 PostMapping(/books)4.4 三者的关系图我们来把这三个注解一次性讲清楚它们是你写 Spring Boot 接口的“三大法宝”。1.RestController—— 类级别的“控制器印章”作用​ 标记一个类是“控制器”专门处理 HTTP 请求并直接把返回值比如字符串、JSON写回给浏览器不经过视图模板。类比​ 就像在 Vue 里给一个组件加上Component装饰器告诉框架“这是我的一块积木”。2.GetMapping—— 方法级别的“GET 请求路由”作用​ 标记一个方法当浏览器发送GET 请求​ 到指定的 URL 时就执行这个方法。例子GetMapping(/hello) public String sayHello() { return 你好; }访问http://localhost:8085/hello就会触发这个方法。特点​ 它是RequestMapping(method RequestMethod.GET)的缩写专门处理 GET 请求。3.RequestMapping—— 更通用的“请求映射”作用​ 既可以放在类上也可以放在方法上用来指定 URL 路径和请求方法GET、POST、PUT、DELETE 等。用法一放在类上给整个控制器加一个公共前缀RestController RequestMapping(/api) // 这个类里所有方法的 URL 都以 /api 开头 public class BookController { GetMapping(/books) // 实际路径是 /api/books public ListBook getAllBooks() { ... } GetMapping(/books/{id}) // 实际路径是 /api/books/{id} public Book getBookById(PathVariable Long id) { ... } }这样做的好处是当你有多个接口都归属同一模块比如书籍相关统一加/api前缀代码更整洁也方便后期统一调整路径。用法二放在方法上等同于GetMapping或PostMappingRequestMapping(value /books, method RequestMethod.GET) // 等价于 GetMapping(/books) RequestMapping(value /books, method RequestMethod.POST) // 等价于 PostMapping(/books)4.3三者的关系图RestController类级别标记这是一个控制器 │ ├── RequestMapping(/api)类级别给所有方法加前缀 │ └── 方法级别 ├── GetMapping(/books) → 等价于 RequestMapping(value/books, methodGET) ├── PostMapping(/books) → 等价于 RequestMapping(value/books, methodPOST) └── RequestMapping(/other, methodPUT) → 直接使用通用注解源码helloworld​五、编写第一个 REST API5.1 创建数据模型在model包下创建Book.javapackage com.example.helloworld.model; // 这个 Book类就是一个“数据容器”用来存放一本书的信息编号、书名、作者。后面你会用 List 装好几个 Book 对象返回给前端。 public class Book { private Long id; private String title; private String author; private String status; // 构造方法 public Book(long id, String title, String author,String status) { this.id id; this.title title; this.status status; } // Getter 方法用于 Spring 自动转 JSON public Long getId() { return id; } public String getAuthor() { return author; } public String getTitle() { return title; } public String getStatus() { return status; } }5.2 创建控制器在controller包下创建BookController.javaRestController RequestMapping(/api) public class BookController { private ListBook books new ArrayList(); public BookController() { books.add(new Book(1L, Spring Boot 实战, 张三, 可借阅)); books.add(new Book(2L, Java 核心技术, 李四, 已借出)); books.add(new Book(3L, 微服务架构设计, 王五, 可借阅)); } GetMapping(/books) public ListBook getAllBooks() { return books; } PostMapping(/books) public Book addBook(RequestBody Book newBook) { newBook.setId((long) (books.size() 1)); books.add(newBook); return newBook; } PutMapping(/books/{id}) public Book updateBook(PathVariable Long id, RequestBody Book updatedBook) { for (Book book : books) { if (book.getId().equals(id)) { book.setTitle(updatedBook.getTitle()); book.setAuthor(updatedBook.getAuthor()); return book; } } return null; } }5.3 测试接口GEThttp://localhost:8085/api/books→ 返回书籍列表JSONPOSThttp://localhost:8085/api/books→ 添加新书Body 传 JSONPUThttp://localhost:8085/api/books/1→ 更新书籍六、连接 MySQL 数据库6.1 安装并启动 MySQL确保 MySQL 服务已安装并运行Windows 可通过services.msc查看 MySQL80 服务状态。6.2 在 pom.xml 中添加 JPA 和 MySQL 依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency添加后点击 IDEA 右下角的 Load Maven Changes​ 下载依赖6.3 创建 application.yml 配置文件在src/main/resources下新建application.yml内容如下server: port: 8085 spring: datasource: url: jdbc:mysql://localhost:3306/bookdb?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: root password: 你的MySQL密码 driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: dialect: org.hibernate.dialect.MySQLDialect format_sql: true注意​ 将password改为你自己的 MySQL root 密码。6.4 在 MySQL 中创建数据库打开 MySQL 命令行或可视化工具执行CREATE DATABASE IF NOT EXISTS bookdb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;6.5 修改 Book 实体类添加 JPA 注解package com.example.backend1.model; import jakarta.persistence.*; Entity // 标记这个类是一个数据库实体 Table(name books) //指定对应的数据库表名为 books // 这个 Book类就是一个“数据容器”用来存放一本书的信息编号、书名、作者。后面你会用 List 装好几个 Book 对象返回给前端。 public class Book { Id //标记 id字段是主键 GeneratedValue(strategy GenerationType.IDENTITY) // 主键自增长 private Long id; Column(nullable false) // 字段不能为空 private String title; Column(nullable false) private String author; Column(nullable false) private String status; // 无参构造方法Spring 反序列化时需要 public Book() { } // 构造方法 全参构造方法 方便在初始化时一次性设置所有字段 // 全参构造方法 public Book(Long id, String title, String author, String status) { this.id id; this.title title; this.author author; this.status status; } // Getter 和 Setter 方法 public Long getId() { return id; } public void setId(Long id) { this.id id; } public String getTitle() { return title; } public void setTitle(String title) { this.title title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author author; } public String getStatus() { return status; } public void setStatus(String status) { this.status status; } }6.6 重启项目观察自动建表启动项目后控制台会输出类似Hibernate: create table books (id bigint not null auto_increment, author varchar(255) not null, status varchar(255) not null, title varchar(255) not null, primary key (id)) engineInnoDB此时bookdb数据库中已自动创建books表。6.7 验证数据持久化由于之前的内存数据已清空GET 请求返回空数组[]。可以通过 POST 请求添加数据数据将存入 MySQL重启后不会丢失。七、遇到的坑与解决7.1 400 Bad Request原因JSON 格式错误或字段类型不匹配如long不能为 null解决将long改为Long确保 JSON 字段名与 Java 属性一致7.2 Required request body is missing原因Postman 中未正确设置 Body 类型为rawJSON解决检查 Postman 请求配置7.3 找不到主类原因编译缓存问题解决执行Build → Rebuild Project或File → Invalidate Caches7.4 数据库连接失败原因MySQL 未启动、密码错误、数据库未创建解决确保 MySQL 服务运行检查application.yml中的连接信息提前创建bookdb数据库八、总结第一周的学习让我完成了✅ 搭建 Spring Boot 开发环境✅ 理解 Maven 和项目结构✅ 掌握 RestController、GetMapping、PostMapping、PutMapping 等核心注解✅ 编写并测试了完整的 REST APICRUD✅ 学会使用 Postman 进行接口调试✅ 配置 MySQL 数据库使用 JPA 自动建表实现数据持久化虽然只是入门但已经能够独立开发带有数据库的后端接口。下一周将深入学习更复杂的查询、异常处理、JWT 鉴权等内容。附录常用命令与工具工具/命令用途java -version查看 JDK 版本mvn clean install清理并重新编译PostmanAPI 测试工具IDEA HTTP Client内置的 API 测试工具.http 文件MySQL Workbench / Navicat数据库可视化管理源码地址helloworld​ backend1