Maven 依賴
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.30</version></dependency>
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency>
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency>
Spring 配置 spring-mvc.xml
<context:component-scan base-package="com.demo.controller"/>
<mvc:annotation-driven/>
<!-- 多部分解析器,支援文件上傳 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600"/> <!-- 100MB -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<!-- 視圖解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
上傳頁面 upload.jsp
<form action="upload.do" method="post" enctype="multipart/form-data">
選擇文件:<input type="file" name="file"/>
<input type="submit" value="上傳"/>
</form>
Controller 實現
@Controller @RequestMapping("/file")
public class FileController {
private static final String UPLOAD_DIR = "C:/uploads/";
@PostMapping("/upload.do")
public String upload(@RequestParam("file") MultipartFile file, RedirectAttributes ra) {
if (file.isEmpty()) { ra.addFlashAttribute("msg", "請選擇文件"); return "redirect:upload.jsp"; }
String original = file.getOriginalFilename();
String saved = System.currentTimeMillis() + "_" + original; // 避免重名
File dest = new File(UPLOAD_DIR, saved);
try { file.transferTo(dest); ra.addFlashAttribute("msg", "上傳成功:" + saved); }
catch (IOException e) { ra.addFlashAttribute("msg", "上傳失敗:" + e.getMessage()); }
return "redirect:upload.jsp";
}
@GetMapping("/download.do")
public ResponseEntity<byte[]> download(@RequestParam String fileName) throws IOException {
File file = new File(UPLOAD_DIR, fileName);
if (!file.exists()) throw new FileNotFoundException("文件不存在:" + fileName);
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment", new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
}
}
關鍵點總結
enctype="multipart/form-data" 表單屬性必加
MultipartFile 參數名需與 <input name="file"> 一致
transferTo() 直接寫磁盤,大文件高效;或用 file.getInputStream() 流式處理
- 下載時
ResponseEntity<byte[]> + Content-Disposition: attachment 觸發瀏覽器下載
- 中文文件名雙重編碼兼容 IE/現代瀏覽器
- 生產環境建議:文件存儲路徑配置化、異步上傳、病毒掃描、對象存儲(OSS/S3)替代本地磁盤