Spring 內建對 Apache Commons FileUpload 的封裝,提供 CommonsMultipartResolver 開箱即用。本文通過動態多文件上傳案例,演示前端動態生成文件域、後端 Controller 處理、Spring 配置全流程。
<form method="post" action="./upload.do" enctype="multipart/form-data">
<div id="uploadDiv">
<input type="file" name="file1" />
</div>
<input type="button" value="繼續上傳" onclick="addFileInput()">
<input type="hidden" id="fileCount" name="fileCount" value="1">
<input type="submit" value="上傳">
</form>
<script>
function addFileInput() {
var count = Number(document.getElementById('fileCount').value) + 1;
var div = document.createElement('div');
div.id = 'divFile' + count;
div.innerHTML = "<input type='file' name='file" + count + "'>";
document.getElementById('uploadDiv').appendChild(div);
document.getElementById('fileCount').value = count;
}
</script>
public class UploadForm {
private byte[] file; // 單文件綁定,多文件由 Request 直接獲取
public byte[] getFile() { return file; }
public void setFile(byte[] file) { this.file = file; }
}
public class FileUploadController extends SimpleFormController {
@Override
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,
Object command, BindException errors) throws Exception {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
int fileCount = Integer.parseInt(request.getParameter("fileCount"));
for (int i = 1; i <= fileCount; i++) {
CommonsMultipartFile file = (CommonsMultipartFile) multipartRequest.getFile("file" + i);
if (file != null && !file.isEmpty()) {
File dest = new File("E:/upload/" + file.getOriginalFilename());
FileCopyUtils.copy(file.getBytes(), dest);
}
}
return new ModelAndView("uploadSuccess");
}
/** 關鍵:註冊 ByteArrayMultipartFileEditor 支援 byte[] 綁定 */
@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
throws ServletException {
binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
}
}
<servlet>
<servlet-name>springStudy</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springStudy</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="50000000"/> <!-- 50MB -->
<property name="defaultEncoding" value="utf-8"/> <!-- 解決中文文件名亂碼 -->
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/upload.do">uploadController</prop>
</props>
</property>
</bean>
<bean id="uploadController" class="com.example.FileUploadController">
<property name="commandClass" value="com.example.UploadForm"/>
<property name="formView" value="uploadForm"/>
<property name="successView" value="uploadSuccess"/>
</bean>
multipart/form-data 內容類型。CommonsMultipartResolver 解析請求,將其包裝為 MultipartHttpServletRequest。CommonsMultipartResolver 繼承 CommonsFileUploadSupport,底層調用 Commons FileUpload API。multipartRequest.getFile(name) 獲取 CommonsMultipartFile,提供 getBytes()、getInputStream()、transferTo(File) 等便捷方法。defaultEncoding="utf-8",Tomcat 8+ 另需 URIEncoding="UTF-8"。maxInMemorySize 閾值,超過寫入臨時文件。ProgressListener 或使用 Servlet 3.0 @MultipartConfig + 異步上傳。spring.servlet.multipart.enabled=true 即可自動配置,無需手動定義 Resolver。