📒 阿里云 OSS + Spring Boot + 異步任務(直接存 OSS)
1. 項目結構
src/main/java/com/example/demo├── controller│ └── UploadController.java // 接收上傳請求├── service│ ├── AsyncUploadService.java // 異步上傳邏輯│ └── OssService.java // OSS 上傳工具類└── DemoApplication.java // 主啟動類
2. Maven 依賴
<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.17.4</version> </dependency>
3. application.properties 配置
# OSS 配置 oss.endpoint=https://oss-cn-hangzhou.aliyuncs.com #你的Endpoint(地域節點)點擊Bucket 列表點擊概覽滑到下面就能看到 oss.access-key-id=你的AccessKeyId oss.access-key-secret=你的AccessKeySecret oss.bucket-name=你的BucketName oss.folder= images
4. OSS 上傳工具類 OssService.java
? ? ? ?oss上放置的資源分私有/公共讀/公共讀寫,我們如果選擇作為圖片/文件服務器時,選擇公共讀、私有寫?,每個文件可以單獨選擇讀寫權限,通過springboot代碼創建文件權限默認和Bucket的一致,如果這句話不太理解可以去看筆者的這篇博客:云服務器--阿里云OSS(1)【阿里云OSS簡單介紹以及環境準備】-CSDN博客
package com.example.demo.service;import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile;import java.io.IOException;@Service public class OssService {@Value("${oss.endpoint}")private String endpoint;@Value("${oss.access-key-id}")private String accessKeyId;@Value("${oss.access-key-secret}")private String accessKeySecret;@Value("${oss.bucket-name}")private String bucketName;@Value("${oss.folder}")private String folder;/*** 直接通過 MultipartFile 的輸入流上傳到 OSS*/public String uploadFile(MultipartFile file, String fileName) throws IOException {OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);// 上傳文件(不落地到磁盤)ossClient.putObject(bucketName, fileName, file.getInputStream());ossClient.shutdown();//endpoint.replace("https://", ""),endpoint會帶有https://,會與前面的矛盾要去掉,endpoint中的https://String path = "https://" + bucketName + "." + endpoint.replace("https://", "") + "/" folder + "/"+ fileName;//可以把路徑保存到數據庫中,前端就可以根據這個路徑訪問了save(path);// 返回 OSS 文件訪問 URLreturn path;} }
5 . 異步上傳服務 AsyncUploadService.java
package com.example.demo.service;import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile;@Service public class AsyncUploadService {@Autowiredprivate OssService ossService;/*** 異步上傳文件到 OSS* @param file 上傳的 MultipartFile* @param fileName 存儲到 OSS 的文件名*/@Async // 異步執行,不阻塞主線程public void upload(MultipartFile file, String fileName) {try {// 直接通過 InputStream 上傳到 OSSossService.uploadFile(file, fileName);System.out.println("文件異步上傳完成:" + fileName);} catch (Exception e) {e.printStackTrace();// 這里可加失敗重試機制}} }
6. 控制器 UploadController.java
?package com.example.demo.controller;import com.example.demo.service.AsyncUploadService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile;import java.util.UUID;@RestController @RequiredArgsConstructor public class UploadController {private final AsyncUploadService asyncUploadService;/*** 接收文件上傳請求*/@PostMapping("/upload")public String upload(@RequestParam("file") MultipartFile file) {// 生成唯一文件名,避免重名覆蓋String fileName = UUID.randomUUID() + "-" + file.getOriginalFilename();// 異步上傳到 OSSasyncUploadService.upload(file, fileName);// 直接返回提示(上傳可能還在進行中)return "文件已接收,正在后臺上傳到 OSS...";} }
7. 啟用異步任務
?package com.example.demo;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication @EnableAsync // 開啟 @Async 支持 public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);} }
🔍 邏輯說明
用戶上傳文件 → 控制器接收
MultipartFile
生成唯一文件名(避免 OSS 覆蓋舊文件)
異步執行上傳(
@Async
標記的方法)直接用
MultipartFile.getInputStream()
上傳到 OSS(避免本地磁盤中轉)返回提示信息(上傳還在后臺進行)
📌 關鍵點
使用 異步任務 避免上傳過程阻塞 HTTP 請求
使用
MultipartFile.getInputStream()
避免文件落地到本地磁盤生產環境可加 失敗重試機制(例如 Spring Retry)
OSS Bucket 權限一般用
公共讀 + 私有寫
公共讀:用戶可直接訪問圖片 URL
私有寫:只有服務器能寫入,防止惡意上傳