文件上傳下載是 Web 開發基礎功能,圖片壓縮則關鍵於存儲成本與傳輸性能。本文提供基於 Servlet/JSP 及 Spring Boot 的完整實現方案,涵蓋多部分解析、流式處理、圖片縮放壓縮等核心技術。
<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 Boot 配置:
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB
@PostMapping("/upload")
public ResponseEntity upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) return ResponseEntity.badRequest().body("文件為空");
try {
String originalName = file.getOriginalFilename();
String savedName = UUID.randomUUID() + "_" + originalName;
Path savePath = Paths.get(UPLOAD_DIR, savedName);
Files.copy(file.getInputStream(), savePath, StandardCopyOption.REPLACE_EXISTING);
return ResponseEntity.ok("上傳成功:" + savedName);
} catch (IOException e) {
log.error("上傳失敗", e);
return ResponseEntity.status(500).body("上傳異常");
}
}
@GetMapping("/download/{fileName}")
public void download(@PathVariable String fileName, HttpServletResponse response) {
Path filePath = Paths.get(UPLOAD_DIR, fileName);
if (!Files.exists(filePath)) {
response.setStatus(404);
return;
}
response.setContentType(Files.probeContentType(filePath));
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
try (InputStream in = Files.newInputStream(filePath);
OutputStream out = response.getOutputStream()) {
IOUtils.copy(in, out);
} catch (IOException e) {
log.error("下載失敗", e);
}
}
使用 Thumbnailator 庫(簡潔高效):
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.18</version>
</dependency>
public byte[] compressImage(byte[] original, float quality, int maxWidth, int maxHeight) throws IOException {
try (ByteArrayInputStream in = new ByteArrayInputStream(original);
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Thumbnails.of(in)
.scale(1.0) // 保持原比例
.size(maxWidth, maxHeight) // 限制最大尺寸
.outputQuality(quality) // 壓縮質量 0.0-1.0
.toOutputStream(out);
return out.toByteArray();
}
}
或使用原生 ImageIO 實現無依賴壓縮。
Files.copy / IOUtils.copyLarge。掌握 Multipart 解析、流式 IO、圖片處理庫的使用,即可構建健壯的文件服務。記住:安全第一,流式第二,異步第三。