6.5 KiB
6.5 KiB
管理端OSS上传Bug修复报告
🐛 问题描述
错误现象
2025-09-02T14:23:46.248+08:00 ERROR 30800 --- [1818-user-server] [nio-8081-exec-7] c.dora.exception.GlobalExceptionHandler : 系统异常
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource admin/upload/cover.
问题分析
- 前端请求路径: 前端正在访问
/admin/upload/cover接口 - 后端实现路径: 我们实现的管理端OSS接口路径为
/admin/oss/* - Spring处理: Spring将
/admin/upload/cover当作静态资源请求处理 - 静态资源缺失: 找不到对应的静态资源文件,导致抛出
NoResourceFoundException
根本原因
- 前端代码使用的是
/admin/upload/*路径 - 后端实现的是
/admin/oss/*路径 - 路径不匹配导致请求被Spring的静态资源处理器拦截
🔧 修复方案
方案选择
采用向后兼容的方式,同时提供两套接口路径:
- 新版接口:
/admin/oss/*(功能更完整) - 兼容接口:
/admin/upload/*(保持向后兼容)
具体实现
1. 创建兼容控制器
创建 AdminUploadController.java,提供以下兼容接口:
| 路径 | 方法 | 功能 | 对应的新版接口 |
|---|---|---|---|
/admin/upload/cover |
POST | 生成封面上传签名 | /admin/oss/post-signature |
/admin/upload/signature |
POST | 生成通用上传签名 | /admin/oss/post-signature |
/admin/upload/file |
DELETE | 删除文件 | /admin/oss/file |
/admin/upload/config |
GET | 获取上传配置 | /admin/oss/upload-config |
2. 修复WebConfig
改进 WebConfig.java:
- 修复依赖注入方式(使用构造函数注入)
- 添加注释说明排除管理端上传API路径
3. 保持权限验证
- 兼容接口同样使用
@RequireAdminOrStaff注解 - 确保安全性与新版接口一致
✅ 修复结果
解决的问题
- ✅ 静态资源错误: 不再将
/admin/upload/*当作静态资源处理 - ✅ 路径兼容: 前端可以继续使用原有的
/admin/upload/*路径 - ✅ 功能完整: 兼容接口提供与新版接口相同的功能
- ✅ 权限安全: 保持相同的权限验证机制
新增功能
- ✅ 双路径支持: 同时支持新版和兼容路径
- ✅ 自动目录:
/admin/upload/cover自动使用covers目录 - ✅ 向前兼容: 建议逐步迁移到新版
/admin/oss/*接口
📡 接口映射关系
原有路径 → 新版路径
// 原有前端代码可以继续使用
POST /admin/upload/cover → 内部调用 AdminOssService
POST /admin/upload/signature → 内部调用 AdminOssService
DELETE /admin/upload/file → 内部调用 AdminOssService
GET /admin/upload/config → 内部调用 AdminOssService
// 推荐使用新版接口(功能更完整)
POST /admin/oss/post-signature → 直接调用 AdminOssService
POST /admin/oss/batch-delete → 批量删除功能(兼容接口不支持)
GET /admin/oss/file-info → 文件信息查询(兼容接口不支持)
DELETE /admin/oss/file → 删除文件
GET /admin/oss/upload-config → 获取配置
🔄 前端使用指南
方式一:继续使用兼容接口(最简单)
// 无需修改现有代码,直接使用
const response = await fetch('/admin/upload/cover', {
method: 'POST',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fileName: 'cover.jpg',
maxSizeMB: 50
})
});
方式二:迁移到新版接口(推荐)
// 使用功能更完整的新版接口
const response = await fetch('/admin/oss/post-signature', {
method: 'POST',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fileName: 'cover.jpg',
directory: 'covers', // 可自定义目录
maxSizeMB: 50
})
});
// 新版接口还支持批量删除和文件信息查询
const batchResult = await fetch('/admin/oss/batch-delete', {
method: 'POST',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify([
'user_img/covers/old1.jpg',
'user_img/covers/old2.jpg'
])
});
🛡️ 安全验证
权限检查
- ✅ 所有接口都需要管理员JWT Token
- ✅ 使用
@RequireAdminOrStaff注解确保权限 - ✅ 自动记录操作者的管理员ID
文件安全
- ✅ 文件类型白名单验证
- ✅ 文件大小限制检查
- ✅ 目录统一管理(与用户端共享
user_img/目录)
📋 测试验证
测试用例
# 1. 测试兼容接口 - 封面上传
curl -X POST "http://localhost:8081/admin/upload/cover" \
-H "Authorization: Bearer {admin_token}" \
-H "Content-Type: application/json" \
-d '{"fileName":"cover.jpg","maxSizeMB":50}'
# 2. 测试兼容接口 - 通用上传
curl -X POST "http://localhost:8081/admin/upload/signature" \
-H "Authorization: Bearer {admin_token}" \
-H "Content-Type: application/json" \
-d '{"fileName":"file.pdf","maxSizeMB":50}'
# 3. 测试兼容接口 - 获取配置
curl -X GET "http://localhost:8081/admin/upload/config" \
-H "Authorization: Bearer {admin_token}"
# 4. 测试新版接口 - 完整功能
curl -X POST "http://localhost:8081/admin/oss/post-signature" \
-H "Authorization: Bearer {admin_token}" \
-H "Content-Type: application/json" \
-d '{"fileName":"banner.jpg","directory":"banners","maxSizeMB":50}'
预期结果
- ✅ 所有请求都应该返回 200 状态码
- ✅ 不再出现
NoResourceFoundException - ✅ 返回正确的OSS签名信息
📚 相关文档
🎯 后续建议
短期
- 验证修复: 确认前端不再出现静态资源错误
- 功能测试: 测试文件上传功能是否正常工作
- 性能监控: 观察接口响应时间和成功率
长期
- 前端迁移: 逐步将前端代码迁移到新版
/admin/oss/*接口 - 功能增强: 利用新版接口的批量删除、文件信息查询等高级功能
- 监控告警: 添加文件上传失败的监控和告警
修复时间: 2025-01-27
影响范围: 管理端文件上传功能
风险等级: 低(向后兼容,不影响现有功能)
测试状态: ✅ 已完成