第五部分:运行与测试
5.1 开发环境配置详解
在运行项目之前,需要确保开发环境正确配置。以下是完整的环境配置指南:
JDK安装与配置:
# 检查JDK版本
java -version
# 应输出类似:openjdk version "11.0.20" 2023-07-18
# 如果未安装,Ubuntu/Debian系统使用:
sudo apt update
sudo apt install openjdk-11-jdk
# Windows系统:从Oracle官网下载JDK11安装包
# 设置JAVA_HOME环境变量
Maven安装与配置:
# 检查Maven版本
mvn -version
# 应输出:Apache Maven 3.8.x
# Ubuntu/Debian安装:
sudo apt install maven
# macOS安装:
brew install maven
Node.js安装:
# 检查Node版本
node -v
# 需要16.0以上版本
# 使用nvm管理Node版本(推荐)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install 18
nvm use 18
MySQL安装与配置:
# Ubuntu/Debian安装MySQL
sudo apt install mysql-server
sudo mysql_secure_installation
# 创建数据库用户
sudo mysql -u root -p
CREATE USER 'library'@'localhost' IDENTIFIED BY 'library123';
GRANT ALL PRIVILEGES ON library_db.* TO 'library'@'localhost';
FLUSH PRIVILEGES;
5.2 启动后端服务的多种方式
方式一:IDE启动(推荐开发阶段)
用IntelliJ IDEA打开library-system项目
等待Maven依赖下载完成
找到LibrarySystemApplication.java
右键 -> Run 'LibrarySystemApplication'
方式二:Maven命令行启动
# 进入后端项目目录
cd library-system
# 清理并编译项目
mvn clean compile
# 运行Spring Boot应用
mvn spring-boot:run
# 或者打包成jar后运行
mvn clean package
java -jar target/library-system-1.0.0.jar
方式三:设置开发环境profile
# 使用开发环境配置运行
mvn spring-boot:run -Dspring-boot.run.profiles=dev
# 指定不同端口运行
mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8081
5.3 启动前端的多种方式
方式一:开发模式启动
# 进入前端项目目录
cd library-ui
# 安装依赖
npm install
# 启动开发服务器
npm run dev
方式二:构建后预览
# 构建生产版本
npm run build
# 预览构建结果
npm run preview
方式三:指定端口启动
# 修改vite.config.js中的server.port
# 或使用命令行参数
npm run dev -- --port 3000
5.4 API接口测试(使用Postman)
Postman测试步骤:
安装Postman:从官网下载并安装
创建测试集合:点击Collections → New Collection → 命名为“图书管理系统”
接口测试清单:
# 1. 登录接口测试
POST http://localhost:8080/api/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "admin123"
}
# 预期响应
{
"code": 200,
"message": "success",
"data": {
"userId": 1,
"username": "admin",
"realName": "系统管理员",
"role": "admin",
"token": "eyJhbGciOiJIUzUxMiJ9...",
"avatar": null
},
"timestamp": 1714212345678
}
# 2. 分页查询图书
GET http://localhost:8080/api/books?pageNum=1&pageSize=10&keyword=Java
Authorization: Bearer {token}
# 3. 借阅图书
POST http://localhost:8080/api/books/borrow?userId=1&bookId=1
Authorization: Bearer {token}
# 4. 获取借阅记录
GET http://localhost:8080/api/books/records/1
Authorization: Bearer {token}
# 5. 归还图书
PUT http://localhost:8080/api/books/return/1
Authorization: Bearer {token}
5.5 完整的功能测试流程




第六部分:总结与扩展
6.1 项目亮点总结
本项目实现的图书管理系统具有以下亮点:
架构层面:
前后端完全分离:前端使用Vue 3,后端使用Spring Boot,通过RESTful API通信
无状态认证:使用JWT替代Session,支持横向扩展
三层架构清晰:Controller → Service → Mapper,职责分明
数据库设计规范:遵循第三范式,字段类型选择合理,索引设计得当
技术层面:
MyBatis Plus简化开发:单表操作无需编写SQL,分页查询一行代码搞定
Spring Security深度集成:认证授权统一管理,方法级权限控制
http://xcfsr.cn
Axios请求封装:统一错误处理,Token自动注入
Element Plus组件化:UI组件复用,开发效率高
用户体验层面:
响应式布局:适配不同屏幕尺寸
加载状态提示:异步操作有Loading效果
操作反馈:成功/失败有明确的消息提示
表单验证:实时校验,减少无效提交
6.2 技术难点解析
难点1:JWT Token刷新机制
当前实现中,Token在24小时后过期,用户需要重新登录。在生产环境中,通常需要实现Token刷新机制:
/**
* 刷新Token
* 使用Refresh Token换取新的Access Token
*/
@PostMapping("/refresh")
public Result<LoginResponse> refreshToken(@RequestHeader("Authorization") String refreshToken) {
// 解析Refresh Token
if (jwtUtils.validateRefreshToken(refreshToken)) {
Long userId = jwtUtils.getUserIdFromRefreshToken(refreshToken);
User user = userService.getById(userId);
String newToken = jwtUtils.generateToken(user.getId(), user.getUsername(), user.getRole());
return Result.success(new LoginResponse().setToken(newToken));
}
return Result.error(401, "Refresh Token无效");
}
难点2:高并发下的库存扣减
在借阅图书时,如果多个用户同时借阅最后一本书,可能会出现超卖问题。解决方案:
@Transactional
public BorrowDTO borrowBook(Long userId, Long bookId) {
// 使用乐观锁(版本号)防止超卖
Book book = bookMapper.selectForUpdate(bookId);
if (book.getStock() <= 0) {
throw new RuntimeException("库存不足");
}
// 使用版本号更新,如果版本号不匹配则重试
int updateCount = bookMapper.decreaseStockWithVersion(bookId, book.getVersion());
if (updateCount == 0) {
// 重试或返回失败
throw new RuntimeException("系统繁忙,请稍后重试");
}
// ... 创建借阅记录
}
难点3:跨域请求处理
前后端分离必然遇到跨域问题。解决方案有三种:
后端CORS配置(本项目采用):
@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:5173")
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true);
}
};
}
}
Nginx反向代理:
location /api/ {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
}
Vite代理(开发环境):
// vite.config.js
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
}