上午 (9:00 - 12:00)
模块一:开营与环境就绪 (1h)
(09:00-09:20) 破冰与课程介绍:
步骤: 自我介绍。
讲解:
展示最终成果(动态演示,而非截图):打开部署好的URL,快速走一遍登录、查单、看详情、改状态的流程。“这是我们三天后,每个人都能亲手做出来的东西。”
讲解项目背景:为什么选航空订单系统?(业务流程清晰、状态变化典型、有外部集成需求)。
讲解技术栈选型:Spring Boot(高效、生态强)、Angular(工程化、适合后台)、Docker/CI/CD(现代软件开发必备技能)。
(09:20-10:00) 环境终检与热身:
步骤: 带领学员git clone <your-repo-url>并git checkout day1-start。
互动: "请大家依次执行java -version, mvn -v, docker ps命令,有问题现在提出。" 。
操作: 启动IDE,导入Maven项目,确保不报错。
模块二:项目架构与数据库设计 (2h)
(10:00-10:45) 架构设计与功能拆解:
步骤: 打开PPT或白板。
讲解 (画图):
画架构图: 从左到右画出浏览器(Angular) -> Web Server(Nginx) -> API网关(Spring Cloud Gateway, 可省略简化) -> 后端(Spring Boot) -> 数据库(MySQL/PostgreSQL)。解释数据流向和各层职责。
功能拆解: 在白板上列出四大核心功能模块,并分解出关键点:
用户认证: 登录(JWT)、登出、权限拦截。
订单管理: CRUD (创建、读取、更新、删除 - 本次简化为CRU)、列表查询、详情查看。
状态机: 订单状态流转逻辑 (待支付 -> 已支付 -> 已出票 | 已取消)。
航班API: 模拟与外部系统对接。
(10:45-12:00) 数据库设计与实践:
步骤:
设计: 在PPT/白板上清晰地画出users, orders, flight_info三张表的ER图。逐个字段讲解其含义、数据类型(VARCHAR, BIGINT, TIMESTAMP, ENUM等)和约束(PRIMARY KEY, FOREIGN KEY, NOT NULL)。
启动数据库: 带领学员打开docker-compose.yml文件(可以预先写好在day1-start分支),讲解image, ports, environment等配置。在终端中运行docker-compose up -d。
验证: 运行docker ps确认数据库容器已启动。
建表 (Live Coding): 打开Navicat,配置数据库连接。亲自手写CREATE TABLE users ...的SQL语句并执行。
互动/练习: "现在,请大家参照ER图,自己动手创建orders和flight_info表。完成后在聊天区扣1。" 讲师巡场指导。提供建表SQL脚本作为备用。
下午 (13:30 - 16:30)
模块三:Spring Boot项目初始化与核心配置 (1.5h)
(13:30-14:15) 项目创建与配置:
步骤:
(如果从零开始) 打开start.spring.io,选择依赖(Spring Web, Spring Data JPA, Spring Security, MySQL/PostgreSQL Driver),生成项目。更好的方式是直接使用day1-start分支已有的pom.xml。
讲解pom.xml: 逐一解释核心依赖的作用。
Live Coding application.properties: 现场编写数据库连接配置 (spring.datasource.url, username, password)、JPA配置 (spring.jpa.hibernate.ddl-auto=update, spring.jpa.show-sql=true)。重点解释ddl-auto的几种模式和show-sql的调试价值。
(14:15-15:00) JPA/Hibernate 实体映射:
步骤 (Live Coding):
创建com.example.model包。
创建User.java实体类。边写边讲:@Entity、@Table、@Id、@GeneratedValue、@Column。
创建Order.java实体类。重点讲解@ManyToOne和@JoinColumn来建立与User的关联关系。
启动应用,展示控制台Hibernate自动生成的建表/更新语句(如果之前是手动建表,这里DDL应无变化)。
互动/练习: "请大家创建FlightInfo.java实体,并与Order建立@OneToOne关联。"
步骤 (Live Coding): 创建UserRepository和OrderRepository接口,继承JpaRepository。强调:“看,我们一行SQL都没写,但已经拥有了完整的CRUD能力。” 运行一个简单的测试来证明。
模块四:核心业务逻辑 - 状态机实现 (1.5h)
(15:30-16:00) 状态机理论与实现:
讲解:
用PPT展示订单状态流转图(待支付 -> 已支付 ...)。
反面教材: “如果我们用一堆if/else来写,会是什么样子?代码会变得难以维护。”
正面引导: “状态机模式,就是把状态和允许的转换规则封装起来。我们用Java的Enum来实现一个简单的、健壮的状态机。”
Live Coding:
创建OrderStatus.java (Enum),包含所有状态。
在OrderService.java中,创建updateStatus(Long orderId, OrderStatus newStatus)方法。
核心逻辑: 在方法内部,获取当前订单状态currentStatus,然后用一个switch或Map来判断currentStatus是否能合法地转换到newStatus。例如:case PENDING_PAYMENT: if (newStatus PAID || newStatus CANCELLED) { ... } else { throw new IllegalStateException(...) }
(16:00-16:30) 单元测试:
步骤 (Live Coding):
在test目录下为OrderService创建测试类。
使用@SpringBootTest注解。
编写测试方法testStateTransition_Success(),验证一个合法的状态转换。
编写测试方法testStateTransition_Failure(),使用assertThrows验证一个非法的转换会抛出预期的异常。强调测试的重要性。
答疑与总结 (16:30 - 17:00)
回顾今天的内容:从0到1搭建了项目骨架、数据库、JPA映射和核心业务逻辑。
预告明天内容:我们将为这些逻辑穿上"API的外衣",并用JWT保护它。
课后作业:完成本期课程内容已经提交github代码
上午 (9:00 - 12:00)
模块一:RESTful API 设计与实现 (1.5h)
(09:00-09:30) RESTful理论回顾:
讲解: 快速回顾REST核心原则:资源(名词)、行为(HTTP方法)、表述(JSON)、无状态。结合本项目API讲解:GET /orders(获取订单集合资源),POST /orders(创建订单资源)。
(09:30-10:30) Controller层实现 (Live Coding):
步骤:
git checkout day2-start (即 day1-end)。
创建OrderController.java,添加@RestController和@RequestMapping("/api/orders")。
注入OrderService。
逐一实现Endpoint:
@GetMapping: 获取订单列表。
@GetMapping("/{id}"): 获取单个订单详情。
@PutMapping("/{id}/status"): 更新订单状态。
实时测试: 每写完一个接口,立即打开Postman,演示如何调用该接口并查看返回结果。让学员跟着操作。
模块二:安全认证与授权 (1.5h)
(10:30-12:00) Spring Security 与 JWT (Live Coding):
步骤:
引入依赖: 确认spring-boot-starter-security和jjwt依赖在pom.xml中。
感受“被保护”: 重启应用,用Postman访问任何API,会收到401/403。“这就是Spring Security的威力,默认全锁。”
创建DTO: 创建LoginRequest.java, AuthResponse.java, OrderDTO.java。讲解为什么需要DTO:隔离内部实体和外部数据,避免敏感信息泄露(如用户密码)。
JWT工具类: 创建JwtUtil.java,包含生成、解析、验证Token的方法。(这部分可以用代码片段,重点讲解逻辑)。
认证入口: 创建AuthController.java,实现POST /api/auth/login。逻辑:校验用户名密码 -> 成功则生成JWT返回。
安全配置: 创建SecurityConfig.java,配置SecurityFilterChain。这是核心:
禁用CSRF(因为是无状态API)。
配置http.authorizeRequests(),permitAll()放行登录接口,其他接口authenticated()。
创建JwtRequestFilter.java,并用addFilterBefore()将其加入过滤器链。
演示: 用Postman先调用登录接口获取Token,然后将Token放入Authorization请求头(Bearer <token>),再去访问受保护的/api/orders接口,验证成功。
下午 (13:30 - 16:30)
模块三:模拟外部API与集成 (1h)
(13:30-14:30) Mock API与服务调用:
步骤 (Live Coding):
创建MockFlightApiController.java。创建一个@GetMapping("/mock/flight-info/{orderId}")接口,直接返回一个写死的JSON字符串或一个Java对象。
讲解: “在真实世界里,我们经常需要调用其他团队或第三方公司的API,这个MockController就是为了模拟这种情况。”
在OrderService的getOrderById方法中,注入RestTemplate或WebClient。
调用MockFlightApiController的接口,获取航班信息。
将获取到的航班信息,与订单信息聚合在一起,返回给OrderDTO。
演示: 调用GET /api/orders/{id}接口,看到返回的JSON中包含了模拟的航班信息。
模块四:API测试与文档 (2h)
(14:30-15:30) API系统性测试:
步骤:
指导学员在Postman中创建一个Collection,名为“航空订单系统”。
依次创建“登录”、“获取订单列表”、“获取订单详情”等请求。
演示高级技巧: 如何在登录请求的Tests脚本中,将返回的Token自动设置为环境变量。这样,其他请求就可以直接引用该环境变量作为Token,无需手动复制粘贴。
(15:30-14:30) API文档自动化 (Swagger/OpenAPI):
步骤 (Live Coding):
在pom.xml中添加springdoc-openapi-ui依赖。
无需任何代码! 重启应用。
展示魔法: 访问http://localhost:8080/swagger-ui.html。一个漂亮的、可交互的API文档页面就出现了。
讲解: 简单介绍@Operation、@ApiResponse等注解,可以如何丰富文档信息。
答疑与总结 (17:00 - 17:30)
回顾今天内容:我们为后端服务构建了完整的、安全的、文档化的RESTful API。
预告明天:前端将登场,消费我们今天构建的API,并最终将整个系统送上云端自动化部署。
课后作业: 完成本课程功能并提交代码。
上午 (9:00 - 12:00)
模块一:Angular前端工程搭建 (1h)
(09:00-10:00) Angular项目初始化与UI库:
步骤 (Live Coding):
git checkout day3-start。
在项目根目录下,新建一个frontend目录。
cd frontend
ng new airline-order-frontend --routing --style=scss (或css)。
讲解项目结构: src/app目录,app.module.ts (模块), app.component.ts (根组件), app-routing.module.ts (路由)。
引入UI库: ng add ng-zorro-antd 或 ng add @angular/material。按照提示完成安装。解释为什么需要UI库:避免重复造轮子,快速构建美观的界面。
模块二:前端页面与服务开发 (2h)
(10:00-12:00) 组件、路由与服务 (Live Coding):
步骤:
创建组件:
ng g c pages/login
ng g c pages/order-list
ng g c pages/order-detail
配置路由: 在app-routing.module.ts中,配置路径到组件的映射关系。
创建服务:
ng g s core/services/auth
ng g s core/services/order
实现AuthService: 编写login()方法,使用HttpClient调用后端的/api/auth/login。成功后,将JWT存入localStorage。
实现OrderService: 编写getOrders(), getOrderById()等方法。
核心:HTTP拦截器 (HttpInterceptor):
ng g interceptor core/interceptors/jwt
在拦截器中,从localStorage读取Token,并将其添加到每个外发请求的Authorization头中。
在app.module.ts中注册拦截器。这是企业级项目标准实践。
开发登录页: 绑定表单数据,调用AuthService.login(),成功后跳转到订单列表页。
下午 (14:00 - 17:00)
模块三:前后端联调与Docker化 (1.5h)
(14:00-15:00) 联调与完成页面:
步骤: 完成订单列表页和详情页的开发,从OrderService获取数据并展示在模板中。
联调: 同时运行后端Spring Boot应用和前端ng serve。确保前端可以正常获取数据。解决常见的CORS跨域问题(在后端Spring Security配置中添加.cors())。
(15:00-15:30) Docker化 (Live Coding):
步骤:
后端Dockerfile: 在Spring Boot项目根目录创建Dockerfile。使用openjdk:17-slim作为基础镜像,复制jar包,暴露8080端口。
前端Dockerfile (多阶段构建): 在Angular项目根目录创建Dockerfile。
Stage 1 (build): FROM node:18 as build,复制package.json,npm install,复制全部代码,npm run build。
Stage 2 (run): FROM nginx:alpine,COPY --from=build /app/dist/... /usr/share/nginx/html。重点讲解多阶段构建的好处:最终镜像非常小,不包含Node.js和编译工具。
编排docker-compose.yml: 在项目总根目录,修改docker-compose.yml,加入frontend和backend服务,配置build上下文、端口映射、depends_on。
模块四:CI/CD与云端部署 (1.5h)
(15:30-16:30) GitHub Actions (Live Coding):
步骤:
讲解CI/CD概念: 在PPT上画出流程图:Git Push -> GitHub Actions -> Build & Test -> Build & Push Image -> Deploy。
在项目根目录创建.github/workflows/ci-cd.yml。
逐段编写YAML文件,并讲解:
name: 工作流名称。
on: 触发条件 (push: branches: [main])。
jobs: 定义任务。
build_and_push: 任务ID。
runs-on: ubuntu-latest。
steps:
uses: actions/checkout@v3
uses: actions/setup-java@v3
uses: actions/setup-node@v3
后端构建与测试: mvn -B package --file pom.xml
前端构建与测试: npm install && npm run build
登录Docker Hub: uses: docker/login-action@v2,使用secrets.DOCKERHUB_USERNAME和secrets.DOCKERHUB_TOKEN。提前指导学员在GitHub仓库设置Secrets。
构建并推送镜像: uses: docker/build-push-action@v4,为前后端分别构建和推送。
部署到EC2: uses: appleboy/ssh-action@master,使用secrets.SSH_PRIVATE_KEY等。执行的脚本是:docker-compose pull && docker-compose up -d。
(16:30-17:00) 最终演示与Show Time:
步骤:
在本地对前端代码做一个微小修改(如"登录"按钮改成"Sign In")。
git add ., git commit -m "feat: change button text", git push origin main。
切换到GitHub仓库的Actions页面,与全体学员一起观看流水线执行过程。 实时解说每个步骤正在做什么。
流水线成功后,刷新部署在AWS上的公开URL。
见证奇迹的时刻:页面上的按钮文字已经自动更新了!
课程总结与成果展示说明 (17:00 - 17:30)
总结: 恭喜大家!我们用三天时间,走完了从需求分析、架构设计、前后端开发、到自动化部署的全过程,这正是现代企业级项目的开发模式。
回顾关键知识点: JPA, 状态机, REST, JWT, Docker, CI/CD。
讲解学员成果展示方案: 再次明确要求(URL、5分钟Demo),鼓励大家在一周内完成并个性化自己的项目。
Q&A : 回答最后的问题,课程结束。
Comments (0)