实验信息
项目 内容 实验名称 搭建 Spring Boot 后端骨架 所属课程 大数据可视化项目实训 / 企业级 Java 后端开发 实验类型 综合设计型 适用专业 大数据技术 配套教程 《阶段一:搭建 Spring Boot 骨架》
一、实验目的
1. 知识目标
理解 Spring Boot 框架在企业级 Java 后端开发中的地位与作用
理解 Maven 项目结构与依赖管理机制
理解 RESTful 接口的基本概念和返回数据格式
理解"三层架构(Controller-Service-Dao)"的设计思想
2. 能力目标(核心)
能独立使用 IntelliJ IDEA + Spring Initializr 创建标准化的 Spring Boot 项目
能正确编写
application.properties配置文件,完成数据库连接配置能阅读并编写
pom.xml,管理项目依赖能按三层架构划分代码包,符合企业代码组织规范
能编写并调试一个完整的 GET 接口,通过浏览器验证
3. 素养目标
培养严谨细致的工程态度(配置规范、命名规范、目录规范)
建立"代码是给团队看的"的协作意识
培养面对报错时主动查日志、查文档、查搜索引擎的问题解决能力
培养"自己动手做出一个能跑的东西"的成就感和工程信心
二、对接岗位与能力点(校企合作特色)
对接岗位 实际工作场景 本实验对应能力 Java 初级开发 入职第一周搭建项目骨架、提交 demo 创建 Spring Boot 工程、目录分层 大数据开发(对外接口) 把分析结果通过接口暴露给前端/BI 工具 理解 REST 接口、JSON 返回格式 后端实习生 跟着导师熟悉项目结构,加新接口 看懂三层架构、知道在哪个包加什么代码
💼 行业说明:本实验完成的内容,相当于一个 Java 后端开发工程师入职第一天到一周内被要求做的事——从 0 创建项目骨架、按规范分包、写第一个能跑的接口。这是后续所有业务开发的起点。
三、实验环境
1. 硬件环境
设备 配置要求 学生 PC CPU i5 及以上、内存 ≥ 8GB、硬盘 50GB+ 服务器 实训机房虚拟机 master(8GB 内存以上) 网络 校园网或互联网(用于下载 Maven 依赖)
2. 软件环境
软件 版本 用途 Windows Windows 10 / 11 学生开发环境 IntelliJ IDEA Ultimate 2022+ Java 集成开发环境 JDK Oracle JDK 1.8 Java 运行与编译环境 Maven 3.6+(IDEA 内置) 依赖管理与项目构建 MySQL 5.7 / 8.0(master) 关系型数据库 Google Chrome / Edge 最新版 接口测试
四、实验原理与知识准备
1. Spring Boot 与企业项目
Spring Boot 是目前国内 Java 后端开发中使用最广泛的框架,几乎所有招聘 Java 开发的岗位都要求掌握。它的核心价值是:
约定优于配置:用合理的默认值代替繁琐的 XML 配置
内嵌 Tomcat:不需要额外部署服务器,一个 jar 包就能跑
生态完整:数据库、缓存、消息队列、监控都有现成的 Starter
💼 企业实战提示:实际项目里,后端工程师不会再用纯 Spring/SSM,基本都用 Spring Boot。所以这一阶段的内容是行业入门门槛。
2. 三层架构(Controller-Service-Dao)
层 职责 类比 Controller 接收 HTTP 请求,返回 JSON 餐厅前台 Service 业务逻辑、数据处理 后厨大厨 Dao 操作数据库 食材采购员
调用方向:Controller → Service → Dao,只能向下,不能反向,不能跨级。
3. RESTful 接口与统一返回格式
企业开发中,后端给前端的所有 JSON 通常都遵循统一格式:
{
"code": 200,
"msg": "ok",
"data": { ... }
}
code:状态码(200=成功,4xx=客户端错误,5xx=服务端错误)msg:消息(成功 ok / 失败错误描述)data:实际数据载荷
💼 企业规范:几乎所有大厂的后端开发规范(阿里、字节、美团)都要求接口返回这种统一格式。学生从一开始就要养成这个习惯。
五、实验内容与任务分解
本实验包含 5 个子任务,按以下顺序完成:
任务 任务名称 建议用时 难度 验收标志 任务1 创建 Spring Boot 项目 30 min ⭐ 项目结构生成,pom.xml 无报错 任务2 配置 application.properties 20 min ⭐ 项目启动,无 DataSource 报错 任务3 完善 pom.xml 30 min ⭐⭐ 依赖下载完成,External Libraries 可见 任务4 创建三层架构包 10 min ⭐ 6 个空包创建完成 任务5 编写健康检查接口 /api/health60 min ⭐⭐ 浏览器返回 {"code":200,"msg":"ok"}
六、实验步骤与参考答案
📖 详细操作过程见配套教程《阶段一》对应任务章节。 本节列出 核心步骤 + 验收点 + 参考代码(含完整注释),学生完成后可对照检查。
任务 1:创建 Spring Boot 项目
1.1 核心操作
IDEA → File → New → Project,选择 Spring Initializr
Service URL 修改为阿里云:
https://start.aliyun.com/项目信息:
Group=com.demo,Artifact=smart-screen-backend,JDK=1.8Spring Boot 版本:2.7.6(不能选 3.x)
勾选 5 个依赖:
Spring Web、JDBC API、MySQL Driver、Lombok、Spring Boot DevTools
1.2 关键技术点
为什么选 Spring Boot 2.7.x?——3.x 要求 JDK 17,本实验用 JDK 8
为什么改 Service URL?——默认地址在国外,国内下载慢甚至超时
1.3 📝 参考配置(填表对照)
字段 正确填法 原因 Name smart-screen-backendMaven 项目名习惯小写 Group com.demoJava 包名必须全小写 Artifact smart-screen-backendMaven 不允许 JDK / Java 1.8 / 8 Spring Boot 2.7 不兼容 打包方式 Jar War 适合传统部署
1.4 ✅ 验收点
序号 验收项 1-1 项目结构正确生成,左侧能看到目录树 1-2 pom.xml 无红色报错1-3 IDEA 右下角 Maven 依赖下载完成
任务 2:配置 application.properties
2.1 核心操作
替换 src/main/resources/application.properties 内容。
2.2 📝 参考代码
📁 路径: src/main/resources/application.properties
# ============================================
# 服务器配置
# ============================================
# 服务器监听地址
# 0.0.0.0 表示监听所有网卡,这样别的机器也能访问本服务
# 如果填 127.0.0.1 或 localhost,则只能本机访问
server.address=0.0.0.0
# 服务器端口号
# Spring Boot 默认就是 8080,这里显式写出是为了让配置一目了然
# 如果 8080 被占用,可以改成 8081、8082 等
server.port=8080
# ============================================
# MySQL 数据源配置(Spring Boot 自动配置)
# ============================================
# 数据库连接 URL
# 格式:jdbc:mysql://主机:端口/数据库名?参数1&参数2
# - master :MySQL 所在的主机名(需在 hosts 里配过映射,或写成 IP)
# - 3306 :MySQL 默认端口
# - rt :数据库名(实时数据库)
# - useSSL=false:不使用 SSL 加密(开发环境)
# - serverTimezone=Asia/Shanghai:防止 MySQL 8.x 报时区异常
spring.datasource.url=jdbc:mysql://master:3306/rt?useSSL=false&serverTimezone=Asia/Shanghai
# 数据库账号
spring.datasource.username=root
# 数据库密码(根据自己环境修改;生产环境严禁明文)
spring.datasource.password=123456
# MySQL 驱动类
# MySQL 8.x 使用 com.mysql.cj.jdbc.Driver(注意中间的 cj)
# MySQL 5.x 使用 com.mysql.jdbc.Driver(没有 cj)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# ============================================
# ClickHouse 配置(自定义,不走 Spring 自动配置)
# ============================================
# 为什么自定义?因为我们后面要在同一个项目里连两个数据源
# (MySQL 走 Spring 自动配置,ClickHouse 我们用工具类手动连)
# ClickHouse JDBC 连接 URL
# - 8123:ClickHouse 的 HTTP 端口(默认),JDBC 走的就是 HTTP
# - iot_report:ClickHouse 中的数据库名
clickhouse.url=jdbc:clickhouse://master:8123/iot_report
# ClickHouse 账号(默认就是 default)
clickhouse.username=default
# ClickHouse 密码(默认为空,本实验环境也为空)
clickhouse.password=
2.3 ✅ 验收点
序号 验收项 2-1 启动后控制台显示 Tomcat started on port(s): 80802-2 无 Failed to configure a DataSource 报错
任务 3:完善 pom.xml
3.1 核心操作
替换项目根目录下的 pom.xml,然后右键项目 → Maven → Reload Project。
3.2 关键技术点
BOM(Bill Of Materials):依赖版本清单,避免不同库版本冲突
<scope>的几个值:compile(默认,编译运行都要) /runtime(只运行时需要) /provided(编译需要但运行时由容器提供) /test(只测试用)
3.3 📝 参考代码
📁 路径: pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
POM:Project Object Model,Maven 项目的"身份证 + 进货单"
作用:
1) 声明项目坐标(groupId/artifactId/version)
2) 引入依赖(进货单:这个项目需要哪些库)
3) 配置构建插件(怎么编译、怎么打包)
-->
<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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- Maven 模型版本,固定写 4.0.0 -->
<modelVersion>4.0.0</modelVersion>
<!-- ====== 项目坐标:三元组,在 Maven 世界里唯一标识一个项目 ====== -->
<groupId>com.demo</groupId> <!-- 组织/公司域名倒写 -->
<artifactId>smart-screen-backend</artifactId> <!-- 项目名(打包后 jar 文件名) -->
<version>1.0.0-SNAPSHOT</version> <!-- SNAPSHOT = 开发版,正式发布去掉 -->
<!-- 项目展示信息(只用于说明,不影响构建) -->
<name>smart-screen-backend</name>
<description>Smart Screen Backend (Spring Boot + MySQL + ClickHouse)</description>
<!-- ====== 全局属性:统一管理版本号 + 编码 ====== -->
<!--
为什么要用 <properties>?
把版本号集中放在一处,改版本时只改一处,不用全文搜索替换。
-->
<properties>
<java.version>1.8</java.version>
<!-- 源码编码:防止中文乱码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring Boot 版本:2.7.x 是兼容 JDK 8 的最后版本 -->
<spring-boot.version>2.7.6</spring-boot.version>
<clickhouse-jdbc.version>0.6.0</clickhouse-jdbc.version>
<lombok.version>1.18.32</lombok.version>
</properties>
<!-- ====== 依赖区:进货单 ====== -->
<dependencies>
<!-- 1) Spring Web
给我们:① REST 接口能力 ② 内置 Tomcat ③ JSON 序列化
相当于"开餐厅必备的厨房设备" -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 2) Spring Data JDBC
给我们:简化版 JDBC 操作能力,包含 JdbcTemplate
阶段二查 MySQL 时会用到 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- 3) MySQL 驱动
scope=runtime:编译时不需要(我们代码里不直接 import 这个),
运行时才需要(Spring 用它创建数据库连接) -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 4) ClickHouse 驱动
阶段三查 ClickHouse 时用 -->
<dependency>
<groupId>com.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>${clickhouse-jdbc.version}</version>
</dependency>
<!-- 5) LZ4 压缩库
ClickHouse 客户端默认用 LZ4 压缩传输数据,缺这个会启动报错 -->
<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
<version>1.8.0</version>
</dependency>
<!-- 6) Apache HttpClient 5
ClickHouse JDBC 0.6.x 需要它来发 HTTP 请求 -->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5</artifactId>
<version>5.2.1</version>
</dependency>
<!-- 7) Lombok
scope=provided:编译时需要,运行时不需要(因为它生成的代码已经在 .class 里了)
用途:用 @Data 注解一行替代几十行 getter/setter -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- 8) DevTools
用途:改代码后自动重启,加快开发节奏
optional=true:你的项目用,但依赖你这个项目的别人不会自动用 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 9) Configuration Processor
用途:写 application.properties 时,有自动补全和文档提示 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- 10) 测试依赖(本实验暂不用,但保留以便后续写单元测试) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- ====== 依赖版本统一管理 ======
引入 Spring Boot 的 BOM(Bill Of Materials),
作用:上面的 Spring 相关依赖都不用写 version,
BOM 会自动给它们指定和 spring-boot.version 匹配的版本 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- ====== 构建插件 ====== -->
<build>
<plugins>
<!-- 编译插件:指定用 Java 8 编译,UTF-8 编码 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<!-- 让 Lombok 注解在编译期生效(否则 @Data 不会生成代码) -->
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<!-- Spring Boot 打包插件
作用:执行 mvn package 时,生成"胖 jar"(把依赖也打进去),
让生成的 jar 可以直接 java -jar xxx.jar 运行 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
3.4 ✅ 验收点
序号 验收项 3-1 pom.xml 无红色波浪线3-2 External Libraries 中能看到 clickhouse-jdbc-0.6.0
任务 4:创建三层架构包
4.1 核心操作
在主包 com.demo.smartscreenbackend 下,右键 → New → Package,依次创建 6 个子包:
com.demo.smartscreenbackend
├── controller ← 接口(收请求,发响应)
├── service ← 业务逻辑(干活)
├── dao ← 查数据库
├── dto ← 数据格式(给前端的"快递盒")
├── config ← 项目配置
└── util ← 工具方法
⚠️ 本任务只建空包,不写代码。代码在任务 5 里一并填进去。
4.2 ✅ 验收点
序号 验收项 4-1 6 个包全部创建完成,命名正确(全小写)
任务 5:编写健康检查接口
5.1 核心操作
按 DTO → Service → Controller 顺序,创建 3 个类:
dto/CommonResp.javaservice/HealthService.javacontroller/HealthController.java
启动后浏览器访问:
http://localhost:8080/api/health
期望返回:
{"code":200,"msg":"ok"}5.2 📝 参考代码(三个类)
5.2.1 CommonResp.java
📁 路径: src/main/java/com/demo/smartscreenbackend/dto/CommonResp.java
// package:声明这个类属于哪个"包"(文件夹)
// 必须和文件实际所在的目录一致,否则编译报错
package com.demo.smartscreenbackend.dto;
/**
* 通用返回对象(DTO - Data Transfer Object)
*
* 作用:
* 所有接口都用它包装返回值,前端只要看 code 就知道成不成功。
*
* 为什么需要它?
* 假设没有这个类,每个接口都自己拼字符串 "{\"code\":200,...}",
* 有 10 个接口就要拼 10 遍,字段一变 10 个地方都要改。
* 有了 CommonResp,所有接口"返回什么"都是统一的盒子,只装不同的菜。
*/
public class CommonResp {
// 状态码:200=成功,500=失败
// 用 Integer(包装类型)而不是 int(基本类型),
// 因为 Integer 允许为 null,JSON 转换更灵活
private Integer code;
// 提示信息:成功时通常是 "ok",失败时是错误原因
private String msg;
/**
* 无参构造方法
* Jackson(Spring 默认 JSON 库)把 JSON 转成 Java 对象时,
* 需要先 new 一个空对象再填值,所以无参构造**必须有**。
*/
public CommonResp() {
}
/**
* 全参构造方法
* 自己写代码时方便:new CommonResp(200, "ok") 一行搞定
*/
public CommonResp(Integer code, String msg) {
// this.code 指当前对象的成员变量
// 右边的 code 是参数,用 this. 区分两个同名变量
this.code = code;
this.msg = msg;
}
// ========== getter / setter ==========
// 字段是 private,外部不能直接 obj.code 访问,必须走这两个方法
// Spring、Jackson 等框架就是靠 getter/setter 给对象赋值/取值的
public Integer getCode() { return code; }
public void setCode(Integer code) { this.code = code; }
public String getMsg() { return msg; }
public void setMsg(String msg) { this.msg = msg; }
}
5.2.2 HealthService.java
📁 路径: src/main/java/com/demo/smartscreenbackend/service/HealthService.java
package com.demo.smartscreenbackend.service;
// 借用 CommonResp:下面方法的返回类型要用它
import com.demo.smartscreenbackend.dto.CommonResp;
// 借用 @Service 注解:告诉 Spring 这是个业务层组件
import org.springframework.stereotype.Service;
/**
* 健康检查业务类(Service - 业务层)
*
* 职责:
* 写"业务逻辑"——判断、计算、组装数据。
*
* 现在只返回 ok,以后想扩展也很容易,比如:
* - 加上 MySQL 连通性检查
* - 加上 ClickHouse 连通性检查
* - 返回当前服务器内存、CPU 使用率
*
* 关键:这些复杂业务都加在 Service 里,Controller 不动。
*/
@Service // 标记为业务层 Bean,Spring 启动时会自动 new 一个并管理它
// 有这个注解,Controller 那边 @Autowired 才能注入进来
public class HealthService {
/**
* 健康检查
* @return 统一格式的返回对象(code=200, msg="ok")
*/
public CommonResp check() {
// 200 是 HTTP 业界通用的"成功"状态码
return new CommonResp(200, "ok");
}
}
5.2.3 HealthController.java
📁 路径: src/main/java/com/demo/smartscreenbackend/controller/HealthController.java
package com.demo.smartscreenbackend.controller;
// 借用别的包里的类
import com.demo.smartscreenbackend.dto.CommonResp;
import com.demo.smartscreenbackend.service.HealthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 健康检查接口(Controller - 接口层)
*
* 职责:
* 接收 HTTP 请求 → 调用 Service 干活 → 把结果返回出去。
* 不做业务、不写 SQL,纯纯的"传话员"。
*/
@RestController // ① 告诉 Spring:这个类专门处理 HTTP 请求,
// 返回值自动转 JSON 发给前端
// = @Controller + @ResponseBody
@RequestMapping("/api") // ② 给这个类下所有接口加 /api 前缀
// 相当于"门牌号的小区名"
public class HealthController {
// @Autowired:自动注入
// 不用自己写 new HealthService(),Spring 启动时已经 new 好一个 Bean,
// 这里直接"借"过来用就行
// 类比:不用自己做饭,外卖平台把做好的菜送上门
@Autowired
private HealthService healthService;
/**
* 健康检查接口
* 完整路径 = 类前缀 + 方法路径 = /api + /health = /api/health
*/
@GetMapping("/health") // ③ 只接受 GET 请求,路径 /health
public CommonResp health() {
// 把活儿丢给 Service,自己只管"接电话、回话"
return healthService.check();
// 返回的 CommonResp 对象会被 Spring 自动序列化成:
// {"code":200,"msg":"ok"}
// 然后写回 HTTP 响应体,浏览器收到。
}
}
5.3 ✅ 验收点
序号 验收项 5-1 3 个类创建完成,注解齐全 5-2 浏览器访问 /api/health 返回 {"code":200,"msg":"ok"}5-3 控制台无报错
七、常见问题处理(FAQ)
序号 问题现象 排查思路 1 Spring Initializr 卡住,依赖下载失败 检查 Service URL 是否改为阿里云;检查网络;检查 Maven settings.xml 是否配置镜像2 Failed to configure a DataSource检查 application.properties 是否保存;检查 url/username/password 是否正确3 Connection timed out: connect(启动报错)检查 master 节点是否启动、MySQL 服务是否运行、防火墙是否放行 3306 4 Port 8080 was already in use查找占用进程并杀掉,或改 server.port=80815 浏览器访问 /api/health 返回 404检查 @RequestMapping("/api") 和 @GetMapping("/health") 是否写对6 浏览器返回 500 错误 查 IDEA 控制台报错堆栈,通常是 Service 注入失败或 NPE 7 Lombok 注解不生效,getter/setter 不存在 IDEA 安装 Lombok 插件;Settings → Build → 开启 annotation processing