基於 Spring + Hibernate + Spring MVC 架構,實現不依賴 Flash 的 HTML5 文件上傳進度條功能。前端採用 Bootstrap 框架,後端自定義 MultipartResolver 監聽上傳進度。
<bean id="multipartResolver" class="com.yunfang.banks.listener.CustomMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
<property name="maxUploadSize" value="10000000000" />
</bean>
public class Progress {
private long pBytesRead;
private long pContentLength;
private long pItems;
// getter/setter/toString 省略
}
@Component
public class FileUploadProgressListener implements ProgressListener {
private HttpSession session;
public void setSession(HttpSession session) {
this.session = session;
session.setAttribute("status", new Progress());
}
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
Progress status = (Progress) session.getAttribute("status");
status.setpBytesRead(pBytesRead);
status.setpContentLength(pContentLength);
status.setpItems(pItems);
}
}
public class CustomMultipartResolver extends CommonsMultipartResolver {
@Autowired
private FileUploadProgressListener progressListener;
@Override
public MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
progressListener.setSession(request.getSession());
FileUpload fileUpload = prepareFileUpload(determineEncoding(request));
fileUpload.setProgressListener(progressListener);
// 解析請求並返回結果
}
}
@RequestMapping("UserControllers/progress")
public void uploadFile(HttpServletRequest request, HttpServletResponse response,
@RequestParam("file") CommonsMultipartFile file) throws IOException {
response.setContentType("text/html;charset=GBK");
boolean flag = file.getSize() > 0 && FileUploadUtil.uploadFile(request, file);
response.getWriter().print(flag ? "1" : "2");
}
public static Boolean uploadFile(HttpServletRequest request, MultipartFile file) {
String path = request.getSession().getServletContext().getRealPath("upload");
File targetFile = new File(path, file.getOriginalFilename());
if (!targetFile.exists()) targetFile.mkdirs();
try {
file.transferTo(targetFile);
return true;
} catch (Exception e) {
return false;
}
}
<progress id="progressBar" value="0" max="100"></progress>
<span id="percentage"></span>
<input type="file" id="file" class="file" />
<input type="button" value="上傳" onclick="UpladFile()" />
<script>
function UpladFile() {
var fileObj = document.getElementById("file").files[0];
var form = new FormData();
form.append("file", fileObj);
var xhr = new XMLHttpRequest();
xhr.open("post", "UserControllers/progress", true);
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percent = Math.round(evt.loaded / evt.total * 100);
document.getElementById("progressBar").value = percent;
document.getElementById("percentage").innerHTML = percent + "%";
}
}, false);
xhr.onload = function() { alert("上傳完成!"); };
xhr.send(form);
}
</script>
ProgressListener 接口,通過 Session 共享進度對象CommonsMultipartResolver,注入監聽器並設置到 FileUploadFormData + XMLHttpRequest 實現無刷新上傳xhr.upload.onprogress 實時更新進度條
本方案純 Java 實現,無需第三方插件,通過 Spring MVC 擴展點結合 HTML5 原生 API,實現了優雅的文件上傳進度反饋,適合企業級應用集成。