<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Multipart 自動配置已內含 -->
application.yml:
web:
upload-path: ${user.dir}/resources/static/ # 專案外部絕對路徑,便於獨立部署
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
resources:
static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${web.upload-path}
static-locations 最後一項 file:${web.upload-path} 讓 Spring Boot 直接服務上傳目錄下的靜態資源。
@RestController
public class FileUploadController {
@Value("${web.upload-path}")
private String uploadRoot;
@Autowired private UserService userService;
@PostMapping(value = "/fileUpload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResultVo upload(@RequestParam("file") MultipartFile file,
@RequestParam("userId") Integer userId) {
ResultVo result = new ResultVo();
if (file.isEmpty()) {
return result.error(0, "請選擇圖片");
}
if (!file.getContentType().startsWith("image/")) {
return result.error(0, "僅支援圖片格式");
}
try {
// 1. 生成唯一檔名
String ext = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
String fileName = System.currentTimeMillis() + "." + ext;
// 2. 使用者專屬目錄
String relDir = "images/upload/" + userId + "/";
File destDir = new File(uploadRoot, relDir);
if (!destDir.exists()) destDir.mkdirs();
// 3. 刪除舊頭像
User user = userService.findById(userId);
if (StringUtils.isNotBlank(user.getAvatar())) {
File old = new File(uploadRoot, user.getAvatar());
if (old.exists()) old.delete();
}
// 4. 保存新檔案
File dest = new File(destDir, fileName);
file.transferTo(dest);
// 5. 更新資料庫(儲存相對路徑,含正斜線)
String relPath = relDir.replace(File.separator, "/") + fileName;
user.setAvatar(relPath);
userService.update(user);
Map<String, Object> data = new HashMap<>();
data.put("file", relPath);
return result.success(data);
} catch (IOException e) {
return result.error(0, "上傳失敗: " + e.getMessage());
}
}
}
file.getContentType().startsWith("image/") 防止偽裝檔案。/ 分隔符,跨平台相容。static-locations 含 file: 協議,Nginx 反向代理時亦可直接服務。<form action="/fileUpload" method="post" enctype="multipart/form-data">
<input type="file" name="file" accept="image/*" required>
<input type="hidden" name="userId" value="123">
<button type="submit">上傳頭像</button>
</form>
Spring Boot 內建 Multipart 支援,配合合理的檔案命名、目錄結構與靜態資源映射,即可快速構建生產級圖片上傳服務。