1. 大文件上传进度监控的业务痛点
在Web应用开发中,文件上传是个老生常谈的话题,但当文件体积超过100MB时,传统的表单提交方式就会暴露出诸多问题。最常见的就是用户无法感知上传进度,就像在黑暗隧道里行走却看不到出口指示灯。我曾接手过一个在线教育平台的项目,课程视频平均大小在300MB左右,后台经常收到用户投诉"上传卡在99%不动了"、"点了上传按钮没反应"。
这种体验问题背后隐藏着三个技术难点:
- HTTP协议的无状态特性导致服务端无法主动推送进度
- 大文件上传耗时较长,浏览器默认不会显示传输进度
- 传统表单提交会阻塞页面交互,用户只能干等
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. SpringMVC拦截器的选型逻辑
2.1 为什么不用过滤器(Filter)?
过滤器虽然能处理请求,但存在两个致命缺陷:
- 无法获取Spring上下文中的Bean,导致业务逻辑处理困难
- 只能读取原始请求流,读取后Controller就无法再次获取参数
java复制// 典型过滤器处理上传的伪代码
public void doFilter(ServletRequest request, ServletResponse response) {
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(request); // 一旦读取流
// Controller层将无法再次获取这个流
}
2.2 拦截器(Interceptor)的三大优势
- 生命周期控制:可以精确控制preHandle、postHandle、afterCompletion三个阶段
- 上下文访问:能直接注入Service等Spring管理的Bean
- 非侵入性:不需要修改现有Controller代码
mermaid复制graph TD
A[客户端请求] --> B[DispatcherServlet]
B --> C[Interceptor.preHandle]
C --> D[Controller]
D --> E[Interceptor.postHandle]
3. 核心实现方案拆解
3.1 进度监控原理设计
采用"分块计数+内存缓存"的方案:
- 前端将文件切分为固定大小块(建议1MB)
- 每个块上传时携带唯一uploadId和chunkIndex
- 拦截器统计已接收块数/总块数计算进度
java复制// 进度缓存数据结构示例
class UploadProgress {
String uploadId;
long totalChunks;
AtomicLong receivedChunks = new AtomicLong();
long lastUpdateTime = System.currentTimeMillis();
}
3.2 拦截器关键代码实现
java复制public class UploadInterceptor implements HandlerInterceptor {
private ConcurrentMap<String, UploadProgress>
