LESSON 5.6 / BACKEND & API

把后端概念迁移到 Java / Spring Boot

Spring Boot 是 Java 后端的一种成熟组织方式。选修本课的重点,是把已有 API 心智模型映射到控制器、服务和数据访问层。

预计阅读约 25 到 40 分钟
完成结果能读懂一个最小任务接口的分层调用,并说明 Java 版本、构建工具和 Spring 依赖从哪里确定。
本课目标
  • 能读懂一个最小任务接口的分层调用,并说明 Java 版本、构建工具和 Spring 依赖从哪里确定。
  • Controller、Service、Repository 的职责
  • 演练把后端概念迁移到 Java / Spring Boot后,应当能读懂一个最小任务接口的分层调用,并说明 Java 版本、构建工具和 Spring 依赖从哪里确定,并保留状态码、响应结构、进程输出和前后端同一次请求作为可重复检查的依据。
开始之前
  • 完成 5.5「完成第一次前后端联调」
01

FOUNDATION

必须理解

框架会变化,但路由、校验、业务逻辑和数据访问的职责可以迁移。把 Next.js 接口映射到 Java/Spring Boot,能理解企业后端常见分层,而不是重新从零背语法。

本课依次讲清Controller、Service、Repository 的职责、依赖注入、配置与环境变量和DTO、校验、异常处理与统一响应,最后通过“用相同五个接口测试对比 Next.js 和 Spring 响应”检查学习结果。

先建立整体直觉

同一份业务流程可以由不同语言的团队执行:窗口名称和制服不同,但受理、校验、处理、存档与回执仍是同一条链。

贯穿本课的实际场景

Next.js 的 route.ts 对应 Spring 的 Controller;独立业务函数对应 Service;Prisma 数据访问对应 Repository/JPA;响应 DTO 固定对外字段。

概念 1

Controller、Service、Repository 的职责

先用白话理解

Java 会在编译时检查很多类型问题,编译后的字节码交给 JVM 运行。Spring Boot 再帮你把应用启动、Web 接口、配置和依赖组织起来。

基础概念

Controller 是 HTTP 入口,Service 承担业务规则,Repository 负责持久化访问。分层让协议、业务与存储变化保持相对独立。

进一步理解

Controller 读取路径、请求体和身份并返回状态;Service 判断任务能否创建或完成;Repository 用 JPA 或 SQL 查询数据库。调用方向通常由入口向内。

小应用可以保持层次轻量,但职责仍应清楚。建立文件不是目的,避免同一规则散落在 Controller 和 Repository 才是价值。

放进实际场景

创建任务由 Controller 接收 DTO,Service 检查项目状态并生成业务结果,Repository 保存实体,Controller 转成 201 响应。

容易混淆的地方

三层不是三台服务器,也不是每个方法都必须机械复制三遍;纯粹的简单读取可能只需很薄的 Service。

这一小节记住:按协议、业务和数据职责分层,而不是按模板堆文件。

概念 2

依赖注入、配置与环境变量

先用白话理解

Controller 先接住 HTTP 请求,Service 处理业务规则,Repository 负责访问数据。分层不是为了多建文件,而是避免改数据库时连接口代码也一起乱掉。

基础概念

依赖注入是由框架把对象需要的协作者交给它,而不是对象内部自行创建;配置与环境变量则为不同运行环境提供地址、凭证和开关。

进一步理解

构造器注入让 Service 明确依赖哪个 Repository,也便于测试时替换实现。Spring 容器负责创建和连接这些对象。

配置代码可以进入版本库,真实秘密通过环境提供。开发、测试和生产使用不同数据源,但字段和校验方式保持一致。

放进实际场景

TaskService 构造器接收 TaskRepository;测试传入内存替身,生产由 Spring 注入连接 PostgreSQL 的实现。

容易混淆的地方

依赖注入不是自动下载依赖,和 Maven 的包依赖管理不同;前者连接运行时对象,后者取得代码库。

这一小节记住:把协作者显式声明并交由外部组装,代码更容易替换和测试。

概念 3

DTO、校验、异常处理与统一响应

先用白话理解

DTO 用来规定接口接收和返回哪些字段,实体模型则更接近数据库。直接把实体整份返回,可能把不该公开的字段也一起送出去。

基础概念

DTO(Data Transfer Object,数据传输对象)规定接口接收或返回的数据形状;校验约束检查输入;异常处理把内部失败映射成统一安全响应。

进一步理解

请求 DTO 只包含调用方允许提交的字段,响应 DTO 只公开需要返回的字段。实体更接近数据库结构,不应直接承担外部契约。

`@Valid` 触发声明式校验,全局异常处理器统一转换常见失败,但业务异常仍需稳定分类,不能全部吞成 500。

放进实际场景

CreateTaskRequest 只接收 title,TaskResponse 返回 id、title、done;ownerId 从会话取得,实体中的内部审计字段不会对外。

容易混淆的地方

统一响应不等于所有结果都包进 200。HTTP 状态码仍应表达协议语义,统一的是错误结构与映射规则。

这一小节记住:DTO 隔离外部契约与内部实体,异常映射保持失败可理解。

Spring Controller 只负责协议入口
运行前先确认
  • Spring Boot 项目已配置 Web 与校验依赖,并存在 taskService。
  • CreateTaskRequest 与 TaskResponse 是明确的请求和响应 DTO。
@PostMapping("/api/tasks")
ResponseEntity<TaskResponse> create(@Valid @RequestBody CreateTaskRequest request) {
    TaskResponse task = taskService.create(request.title());
    return ResponseEntity.status(HttpStatus.CREATED).body(task);
}
这段代码在做什么

阅读把后端概念迁移到 Java / Spring Boot示例时,Controller 接收 HTTP 与校验结果,业务创建逻辑交给 Service,接口仍返回 201。

  1. @PostMapping 把 POST /api/tasks 交给当前方法。
  2. @Valid 在进入业务逻辑前校验请求 DTO,@RequestBody 读取 JSON。
  3. Controller 调用 Service 并用 ResponseEntity 返回 201,不在入口中直接写数据库。
你应该观察到

合法请求得到 201 与 TaskResponse;DTO 校验失败进入统一 400 错误处理;业务创建逻辑可在不启动 HTTP 的测试中单独验证。

02

AI COLLABORATION

AI 如何参与

在把后端概念迁移到 Java / Spring Boot这一课,AI 负责根据真实材料解释Controller、Service、Repository 的职责并指出遗漏,学习者负责控制范围、执行修改和核对状态码、响应结构、进程输出和前后端同一次请求。

推荐协作顺序

  1. 1

    把已经跑通的 Next.js 接口契约给 AI,要求保持 JSON 不变。

  2. 2

    让它先做职责对应表,再写 Spring 的最小骨架。

  3. 3

    用同一组请求分别调用两套后端,比较状态码和正文。

可直接使用的 Prompt
请只依据当前构建文件和依赖解释这个 Spring Boot 项目。先画请求从 Controller 到 Service 再到 Repository 的路径,再说明启动与测试方式。不要猜版本,不添加未声明依赖。
应该得到什么

同一接口契约在不同框架下保持一致,代码边界清楚,不把全部逻辑放进 Controller;把后端概念迁移到 Java / Spring Boot的人工验收必须回到真实页面、请求、终端、测试或数据结果,不能用 AI 的文字说明代替。

人工检查清单

  • 确认 Bean Validation 在服务端生效,DTO 与实体分离,异常不会把堆栈直接返回用户。
  • 让 AI 把现有接口逐项映射到 Controller、Service、Repository 和 DTO,并解释每层存在理由。
  • 用相同请求与预期响应同时测试旧实现和 Spring 实现,确认迁移没有改变契约。
03

COMMON TRAPS

常见误区

下面三类问题会让任务看似完成,却经不起刷新、错误输入或真实环境检查。先看现象,再找原因和修正方法。

误区 1

照抄不同版本教程

你会看到
注解或配置与当前依赖不匹配
为什么发生
框架的配置和 API 会随版本变化,示例与当前依赖不一致就无法直接成立。
怎样纠正
先读取构建文件和官方对应文档
误区 2

为了分层制造空代码

你会看到
每层只转发参数却增加跳转
为什么发生
只转发参数的层没有承担规则,却增加了阅读路径和修改位置。
怎样纠正
按真实职责决定边界
误区 3

把秘密写入配置文件

你会看到
数据库凭证进入仓库
为什么发生
被 Git 跟踪的配置会进入历史和协作副本,秘密难以限制在运行环境。
怎样纠正
从环境注入并提交安全示例
04

HANDS-ON

动手任务

能读懂一个最小任务接口的分层调用,并说明 Java 版本、构建工具和 Spring 依赖从哪里确定。

准备条件
  • 完成 5.5「完成第一次前后端联调」

跟着做

  1. 01

    画出 Next.js Route Handler 的输入、处理和输出。

  2. 02

    将它映射到 Spring 五个常见角色。

  3. 03

    创建最小 Spring Boot Web 项目并运行健康页面。

  4. 04

    实现内存版 GET/POST Tasks Controller 与 Service。

  5. 05

    用相同五个接口测试对比 Next.js 和 Spring 响应。

完成标志

能读懂一个最小任务接口的分层调用,并说明 Java 版本、构建工具和 Spring 依赖从哪里确定。

加餐挑战

解释为什么团队可能选择 Spring Boot 后端,并列出它带来的额外学习与部署成本。

离开本课前,自问四件事

  • Controller、Service 与 Repository 的边界如何沿一次请求划分?
  • 依赖注入与包管理解决的是哪两类不同问题?
  • DTO 为什么不能简单等同于数据库实体?
  • 如何证明从其他技术栈迁移到 Spring 后接口契约保持不变?
完成本课了吗?

确认完成后,会同步更新学习中心的课程学习进度。