1. 项目概述:基于AES加密的SpringBoot教学资源推荐系统
这个毕业设计项目融合了当下企业级开发中最热门的几个技术点:SpringBoot框架、AES数据加密、个性化推荐算法以及MySQL数据库。我在实际开发教育类系统时发现,教学资源的隐私保护和智能推荐是两个最关键的痛点。这个系统正好同时解决了这两个问题——用AES实现资源的安全存储,用推荐算法提升资源获取效率。
系统主要面向高校师生群体,解决三个核心问题:
- 教学资源(课件、视频、习题等)的加密存储与安全传输
- 基于用户行为的个性化推荐
- 高并发场景下的稳定访问体验
技术栈选择非常典型:
- 后端:SpringBoot 2.7 + MyBatis Plus
- 安全:AES-256-CBC加密
- 数据库:MySQL 8.0
- 前端:Thymeleaf + Bootstrap
- 推荐引擎:基于用户的协同过滤算法
提示:选择AES而不是RSA是因为教学资源通常是大文件,AES的对称加密特性更适合这种场景,加解密速度比非对称加密快数十倍。
2. 核心模块设计与实现
2.1 AES加密模块实现
我采用Java自带的javax.crypto包实现AES加密,这是最稳妥的方案。关键点在于:
java复制// AES工具类核心代码
public class AESUtil {
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
private static final byte[] IV = "1234567890123456".getBytes(); // 固定IV仅用于演示
public static byte[] encrypt(byte[] data, String key) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivSpec = new IvParameterSpec(IV);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
return cipher.doFinal(data);
}
// 解密方法类似...
}
实际项目中需要注意:
- 密钥管理:千万不要像示例这样硬编码密钥!应该采用环境变量或密钥管理系统
- IV生成:每次加密应该生成随机IV,和密文一起存储
- 模式选择:CBC模式需要Padding,对文本文件更友好
踩坑记录:初期测试时发现加密后的PPT文件无法打开,原因是未处理二进制流。解决方案是统一采用字节数组操作,而不是字符串转换。
2.2 推荐系统实现
采用基于用户的协同过滤(UserCF)算法,主要步骤:
- 构建用户-资源评分矩阵(隐式反馈)
- 计算用户相似度(余弦相似度)
- 生成推荐列表(Top-K最近邻)
java复制// 相似度计算示例
public double cosineSimilarity(Map<Long, Double> user1, Map<Long, Double> user2) {
double dotProduct = 0.0;
double norm1 = 0.0;
double norm2 = 0.0;
for (Long key : user1.keySet()) {
if (user2.containsKey(key)) {
dotProduct += user1.get(key) * user2.get(key);
}
norm1 += Math.pow(user1.get(key), 2);
}
for (Double value : user2.values()) {
norm2 += Math.pow(value, 2);
}
return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
}
性能优化技巧:
- 使用Redis缓存用户相似度矩阵
- 采用分批次计算策略
- 对稀疏矩阵使用压缩存储
2.3 数据库设计
核心表结构设计:
| 表名 | 字段 | 说明 |
|---|---|---|
| t_user | user_id, username, password(salted_hash), major | 用户表 |
| t_resource | res_id, encrypted_path, original_name, uploader, upload_time | 资源元数据 |
| t_user_resource | id, user_id, res_id, view_count, download_count | 用户行为记录 |
| t_key_management | key_id, user_id, encrypted_key, iv | 密钥管理表 |
特别注意:
- 资源实际内容以加密形式存储在文件系统
- 密钥单独管理,采用主密钥二次加密
- 用户行为记录是推荐系统的数据基础
3. 关键问题解决方案
3.1 大文件加密性能优化
实测加密1GB视频文件时的性能对比:
| 方案 | 耗时 | CPU占用 | 内存消耗 |
|---|---|---|---|
| 直接AES加密 | 28s | 95% | 1.2GB |
| 分块加密(1MB) | 32s | 65% | 50MB |
| 并行分块加密 | 18s | 100% | 200MB |
最终采用分块加密方案,核心代码:
java复制public void encryptFile(Path source, Path target, String key) throws Exception {
try (InputStream in = Files.newInputStream(source);
OutputStream out = Files.newOutputStream(target)) {
byte[] buffer = new byte[1024 * 1024]; // 1MB块
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
byte[] encrypted = AESUtil.encrypt(
Arrays.copyOf(buffer, bytesRead), key);
out.write(encrypted);
}
}
}
3.2 冷启动问题处理
新用户/新资源没有行为数据时,采用混合推荐策略:
- 基于用户专业的资源热度榜
- 基于上传者的其他资源
- 随机展示高质量资源(人工标注)
sql复制-- 专业热度榜SQL示例
SELECT r.res_id, r.original_name, COUNT(ur.download_count) as hot
FROM t_resource r
JOIN t_user_resource ur ON r.res_id = ur.res_id
JOIN t_user u ON r.uploader = u.user_id
WHERE u.major = #{major}
GROUP BY r.res_id
ORDER BY hot DESC
LIMIT 20;
3.3 高并发场景应对
使用SpringBoot的缓存和异步机制:
- 资源下载采用限流器:
java复制@Bean
public RateLimiter downloadRateLimiter() {
return RateLimiter.create(50); // 每秒50个请求
}
- 推荐计算异步化:
java复制@Async
public void updateRecommendations(Long userId) {
// 耗时计算任务
}
- 数据库连接池配置:
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
connection-timeout: 30000
4. 部署与测试要点
4.1 系统部署方案
推荐使用Docker Compose部署:
dockerfile复制version: '3'
services:
app:
image: openjdk:11-jre
ports:
- "8080:8080"
volumes:
- ./data:/var/lib/resources
environment:
- SPRING_PROFILES_ACTIVE=prod
- AES_MASTER_KEY=${AES_MASTER_KEY}
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=resource_db
volumes:
- ./mysql:/var/lib/mysql
关键安全措施:
- 主密钥通过环境变量注入
- 加密资源单独挂载卷
- MySQL数据持久化
4.2 压力测试结果
使用JMeter模拟100并发用户:
| 接口 | 平均响应时间 | 错误率 | TPS |
|---|---|---|---|
| 资源下载 | 320ms | 0% | 285 |
| 推荐获取 | 150ms | 0% | 620 |
| 文件上传 | 1.2s | 0% | 45 |
优化建议:
- 上传接口采用分片上传
- 推荐结果增加本地缓存
- 静态资源走CDN
5. 开发经验总结
在真实项目开发中,有几个容易忽视但至关重要的点:
- 密钥轮换策略:建议每月更换一次主密钥,旧密钥解密后重新用新密钥加密。我们实现了自动化脚本:
bash复制#!/bin/bash
# 密钥轮换示例
for file in $(find /data -type f); do
old_key=$(get_old_key)
new_key=$(generate_new_key)
temp_file=$(decrypt $file $old_key)
encrypt $temp_file $new_key
done
-
资源预览方案:加密的PDF/PPT无法直接预览,我们的解决方案是:
- 上传时自动生成缩略图
- 对文本类资源提取前200字作为摘要
- 视频资源提取关键帧
-
行为数据埋点:除了基础的浏览下载,我们还收集:
- 页面停留时间
- 搜索关键词
- 资源评分(五星制)
这个项目最值得深入的两个方向是:
- 推荐算法优化:尝试加入深度学习模型
- 安全增强:实现国密SM4加密方案
