Springboot集成阿里云OSS上傳

Springboot集成阿里云OSS上傳

API 接口描述

DEMO提供的四個API接口,支持不同方式的文件和 JSON 數據上傳:

1. 普通文件上傳接口

上傳任意類型的文件

2. JSON 字符串上傳接口

上傳 JSON 字符串

3. 單個 JSON 壓縮上傳接口

上傳并壓縮 JSON 字符串

4. 批量 JSON 壓縮上傳接口

批量上傳并壓縮多個 JSON 字符串

AliOssConfig

/*** @author Melody* @description:* @date 2025-05-06*/
@Data
@Configuration
public class AliOssConfig {@Value("${aliyun.oss.endpoint}")private String endpoint;@Value("${aliyun.oss.access-key-id}")private String accessKeyId;@Value("${aliyun.oss.access-key-secret}")private String accessKeySecret;@Value("${aliyun.oss.bucket-name}")private String bucketName;
}

AliOssUtil

/*** @author Melody* @description:* @date 2025-05-06*/
@Component
@Slf4j
public class AliOssUtil {private final AliOssConfig aliOssConfig;private OSS ossClient;@Autowiredpublic AliOssUtil(AliOssConfig aliOssConfig) {this.aliOssConfig = aliOssConfig;ossClient = new OSSClientBuilder().build(aliOssConfig.getEndpoint(), aliOssConfig.getAccessKeyId(), aliOssConfig.getAccessKeySecret());}public String uploadFile(MultipartFile file, String fileType) {if (file.isEmpty()) {throw new IllegalArgumentException("文件不能為空");}try {// 生成文件名和路徑String fileName = generateUniqueFileName(file.getOriginalFilename());String filePath = generateDateBasedFilePath(fileType, fileName);// 上傳文件try (InputStream inputStream = file.getInputStream()) {ossClient.putObject(aliOssConfig.getBucketName(), filePath, inputStream);}// 返回 URLreturn buildOssUrl(filePath);} catch (IOException e) {throw new RuntimeException("文件讀取失敗: " + e.getMessage());} catch (OSSException | ClientException e) {throw new RuntimeException("OSS服務異常: " + e.getMessage());}}/*** 生成唯一文件名(UUID + 擴展名)*/private String generateUniqueFileName(String extension) {return UUID.randomUUID() + extension;}/*** 提取文件擴展名(處理無擴展名的情況)*/private String getFileExtension(String originalFilename) {if (originalFilename == null) return ".dat";int lastDotIndex = originalFilename.lastIndexOf(".");return (lastDotIndex == -1) ? ".dat" : originalFilename.substring(lastDotIndex);}/*** 生成基于日期的存儲路徑(如 images/2024/06/15/uuid.jpg)*/private String generateDateBasedFilePath(String fileType, String fileName) {if (StringUtils.isEmpty(fileType)) {fileType = "file";}String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));return String.format(fileType + "/%s/%s", datePath, fileName);}/*** 構建 OSS 訪問 URL*/private String buildOssUrl(String filePath) {return String.format("https://%s.%s/%s",aliOssConfig.getBucketName(),aliOssConfig.getEndpoint(),filePath);}/*** 上傳json文件到OSS* @param json* @param fileType* @param fileName*/public String uploadJSONToOSS(String json, String fileType, String fileName) {// 創建 OSSClient 實例try {String filePath = generateDateBasedFilePath(fileType, fileName + ".json");// 將 JSON 字符串轉換為字節數組輸入流ByteArrayInputStream inputStream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));PutObjectRequest putObjectRequest = new PutObjectRequest(aliOssConfig.getBucketName(), filePath, inputStream);ossClient.putObject(putObjectRequest);return buildOssUrl(filePath);} catch (Exception e) {log.error("文件上傳失敗:" + e.getMessage());return "";}}/*** 將JSON內容壓縮為ZIP并上傳到OSS* @param json JSON字符串* @param fileType 文件分類(如images、docs)* @param fileName 文件名(不含擴展名)* @return 上傳后的OSS訪問URL*/public String uploadCompressedJSONToOSS(String json, String fileType, String fileName) {ByteArrayOutputStream baos = new ByteArrayOutputStream();try (ZipOutputStream zos = new ZipOutputStream(baos)) {// 創建ZIP條目并添加JSON內容ZipEntry zipEntry = new ZipEntry(fileName + ".json");zos.putNextEntry(zipEntry);zos.write(json.getBytes(StandardCharsets.UTF_8));zos.closeEntry();// 確保ZIP流完全關閉后再獲取字節數組} catch (IOException e) {log.error("JSON壓縮失敗", e);return "";}// 生成帶日期的ZIP文件路徑String filePath = generateDateBasedFilePath(fileType, fileName + ".zip");// 上傳到OSStry (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray())) {OSS ossClient = new OSSClientBuilder().build(aliOssConfig.getEndpoint(),aliOssConfig.getAccessKeyId(),aliOssConfig.getAccessKeySecret());try {PutObjectRequest putRequest = new PutObjectRequest(aliOssConfig.getBucketName(),filePath,bais);ossClient.putObject(putRequest);return buildOssUrl(filePath);} finally {ossClient.shutdown();}} catch (IOException e) {log.error("ZIP文件上傳失敗", e);return "";}}/*** 將多個JSON內容壓縮為ZIP并上傳到OSS* @param jsonMap JSON字符串映射,鍵為文件名(不含擴展名),值為JSON內容* @param fileType 文件分類(如images、docs)* @param zipFileName 生成的ZIP文件名(不含擴展名)* @return 上傳后的OSS訪問URL*/public String uploadMultipleJSONsToOSS(Map<String, String> jsonMap, String fileType, String zipFileName) {ByteArrayOutputStream baos = new ByteArrayOutputStream();try (ZipOutputStream zos = new ZipOutputStream(baos)) {// 遍歷所有JSON內容,為每個JSON創建ZIP條目for (Map.Entry<String, String> entry : jsonMap.entrySet()) {String fileName = entry.getKey();String jsonContent = entry.getValue();// 創建ZIP條目并添加JSON內容ZipEntry zipEntry = new ZipEntry(fileName + ".json");zos.putNextEntry(zipEntry);zos.write(jsonContent.getBytes(StandardCharsets.UTF_8));zos.closeEntry();}} catch (IOException e) {log.error("JSON壓縮失敗", e);return "";}// 生成帶日期的ZIP文件路徑String filePath = generateDateBasedFilePath(fileType, zipFileName + ".zip");// 上傳到OSStry (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray())) {OSS ossClient = new OSSClientBuilder().build(aliOssConfig.getEndpoint(),aliOssConfig.getAccessKeyId(),aliOssConfig.getAccessKeySecret());try {PutObjectRequest putRequest = new PutObjectRequest(aliOssConfig.getBucketName(),filePath,bais);ossClient.putObject(putRequest);return buildOssUrl(filePath);} finally {ossClient.shutdown();}} catch (IOException e) {log.error("ZIP文件上傳失敗", e);return "";}}/*** 刪除文件*/public void deleteFile(String filePath) {ossClient.deleteObject(aliOssConfig.getBucketName(), filePath);}
}    

AliOssController

/*** @author Melody* @description:* @date 2025-05-06*/
@RestController
@RequestMapping("/system/file")
public class AliOssController {private final AliOssUtil aliOssUtil;public AliOssController(AliOssUtil aliOssUtil) {this.aliOssUtil = aliOssUtil;}/*** 阿里云OSS文件上傳*/@PostMapping("/upload")public SysFileDTO uploadFile(MultipartFile file,@RequestParam(value = "fileType", required = false) String fileType) {String url = aliOssUtil.uploadFile(file, fileType);logger.info("上傳文件路徑:" + url);return SysFileDTO.builder().url(url).build();}/*** 阿里云OSS文件上傳*/@PostMapping("/uploadJSONToOSS")public SysFileDTO uploadJSONToOSS(@RequestParam(value = "jsonData") String jsonData) {String url = aliOssUtil.uploadJSONToOSS(jsonData, "json", "example");logger.info("上傳文件路徑:" + url);return SysFileDTO.builder().url(url).build();}/*** 阿里云OSS文件上傳壓縮后的json文件*/@PostMapping("/uploadCompressedJSONToOSS")public SysFileDTO uploadCompressedJSONToOSS(@RequestParam(value = "jsonData") String jsonData) {String url = aliOssUtil.uploadCompressedJSONToOSS(jsonData, "json", "example");logger.info("上傳文件路徑:" + url);return SysFileDTO.builder().url(url).build();}/*** 阿里云OSS文件上傳壓縮后的json文件*/@PostMapping("/uploadMultipleJSONsToOSS")public SysFileDTO uploadMultipleJSONsToOSS(@RequestParam(value = "jsonData") String jsonData) {Map<String, String> jsonMap = new HashMap<>();jsonMap.put("data1", jsonData);jsonMap.put("data2", "{\"key2\":\"value2\"}");String url = aliOssUtil.uploadMultipleJSONsToOSS(jsonMap, "json", "combined");logger.info("上傳文件路徑:" + url);return SysFileDTO.builder().url(url).build();}
}

application.yml

# 阿里云OSS配置
aliyun:oss:endpoint: endpointaccessKeyId: accessKeyIdaccessKeySecret: accessKeySecretbucketName: bucketName

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88051.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88051.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88051.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

刪除大表數據注意事項

數據庫是否會因刪除操作卡死&#xff0c;沒有固定的 “安全刪除條數”&#xff0c;而是受數據庫配置、表結構、操作方式、當前負載等多種因素影響。以下是關鍵影響因素及實踐建議&#xff1a; 一、導致數據庫卡死的核心因素 硬件與數據庫配置 CPU / 內存瓶頸&#xff1a;刪除…

Redis 是單線程模型?|得物技術

一、背景 使用過Redis的同學肯定都了解過一個說法&#xff0c;說Redis是單線程模型&#xff0c;那么實際情況是怎樣的呢&#xff1f; 其實&#xff0c;我們常說Redis是單線程模型&#xff0c;是指Redis采用單線程的事件驅動模型&#xff0c;只有并且只會在一個主線程中執行Re…

[特殊字符] AIGC工具深度實戰:GPT與通義靈碼如何徹底重構企業開發流程

&#x1f50d; 第一模塊&#xff1a;理念顛覆——為什么AIGC不是“玩具”而是“效能倍增器”&#xff1f; ▍企業開發的核心痛點圖譜&#xff08;2025版&#xff09; ??研發效能瓶頸??&#xff1a;需求膨脹與交付時限矛盾持續尖銳&#xff0c;傳統敏捷方法論已觸天花板?…

(LeetCode 面試經典 150 題) 169. 多數元素(哈希表 || 二分查找)

題目&#xff1a;169. 多數元素 方法一&#xff1a;二分法&#xff0c;最壞的時間復雜度0(nlogn)&#xff0c;但平均0(n)即可。空間復雜度為0(1)。 C版本&#xff1a; int nnums.size();int l0,rn-1;while(l<r){int mid(lr)/2;int ans0;for(auto x:nums){if(xnums[mid]) a…

(17)java+ selenium->自動化測試-元素定位大法之By css上

1.簡介 CSS定位方式和xpath定位方式基本相同,只是CSS定位表達式有其自己的格式。CSS定位方式擁有比xpath定位速度快,且比CSS穩定的特性。下面詳細介紹CSS定位方式的使用方法。相對CSS來說,具有語法簡單,定位速度快等優點。 2.CSS定位優勢 CSS定位是平常使用過程中非常重要…

【軟考高級系統架構論文】企業集成平臺的技術與應用

論文真題 企業集成平臺是一個支持復雜信息環境下信息系統開發、集成和協同運行的軟件支撐環境。它基于各種企業經營業務的信息特征,在異構分布環境(操作系統、網絡、數據庫)下為應用提供一致的信息訪問和交互手段,對其上運行的應用進行管理,為應用提供服務,并支持企業信息…

i.MX8MP LVDS 顯示子系統全解析:設備樹配置與 DRM 架構詳解

&#x1f525; 推薦&#xff1a;《Yocto項目實戰教程&#xff1a;高效定制嵌入式Linux系統》 京東正版促銷&#xff0c;歡迎支持原創&#xff01; 鏈接&#xff1a;https://item.jd.com/15020438.html i.MX8MP LVDS 顯示子系統全解析&#xff1a;設備樹配置與 DRM 架構詳解 在…

keep-alive實現原理及Vue2/Vue3對比分析

一、keep-alive基本概念 keep-alive是Vue的內置組件&#xff0c;用于緩存組件實例&#xff0c;避免重復渲染。它具有以下特點&#xff1a; 抽象組件&#xff1a;自身不會渲染DOM&#xff0c;也不會出現在父組件鏈中包裹動態組件&#xff1a;緩存不活動的組件實例&#xff0c;…

安卓jetpack compose學習筆記-Navigation基礎學習

目錄 一、Navigation 二、BottomNavigation Compose是一個偏向靜態刷新的UI組件&#xff0c;如果不想要自己管理頁面切換的復雜狀態&#xff0c;可以以使用Navigation組件。 頁面間的切換可以NavHost&#xff0c;使用底部頁面切換欄&#xff0c;可以使用腳手架的bottomBarNav…

基于大數據技術的在UGC數據分析與路線推薦的研究

博主介紹&#xff1a;java高級開發&#xff0c;從事互聯網行業六年&#xff0c;熟悉各種主流語言&#xff0c;精通java、python、php、爬蟲、web開發&#xff0c;已經做了六年的畢業設計程序開發&#xff0c;開發過上千套畢業設計程序&#xff0c;沒有什么華麗的語言&#xff0…

flask通過表單自動產生get請求的參數、form表單實現POST請求的自動提交

通過表單自動產生get請求的參數 相關代碼如下&#xff1a; import flaskapp flask.Flask(__name__)app.route(/) def login():html <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><title>flask表單實現get…

《情感反詐模擬器》2025學習版

1.2 專業內容支持 67篇情感詐騙案例研究14萬字心理學分析資料783條專業配音對白 二、安裝與運行 2.1 系統要求 最低配置&#xff1a; 顯卡&#xff1a;GTX 1060CPU&#xff1a;i5-8400存儲&#xff1a;25GB空間 2.2 運行步驟 解壓游戲文件&#xff08;21.7GB&#xff09;…

預訓練 vs. 微調:大模型落地的核心兩步,究竟有何不同?

在人工智能領域&#xff0c;尤其是自然語言處理&#xff08;NLP&#xff09;和計算機視覺&#xff08;CV&#xff09;&#xff0c;大型模型如GPT系列、BERT、Stable Diffusion等取得了令人矚目的成就。支撐這些模型廣泛應用的關鍵技術流程&#xff0c;通常包含兩個核心階段&…

微信原生小程序轉uniapp過程及錯誤總結

https://ask.dcloud.net.cn/article/35786 此文章尤為重要&#xff0c;可以使用輔助工具 1、this.setData 源代碼&#xff1a; this.setData({dateTime: obj.dateTime, });需更換為 this.dateTime obj.dateTime2、cookie問題 在此文章有解釋 https://blog.csdn.net/ni155…

關于Spring JBDC

一、什么是Spring JDBC&#xff1f; 什么是JDBC&#xff1f; JDBC&#xff08;Java Database Connectivity&#xff09;是 Java 語言訪問數據庫的標準 API&#xff0c;它定義了一組接口和類&#xff0c;允許 Java 程序與各種數據庫進行交互。JDBC 提供了執行 SQL 語句、處理結果…

【SpringBoot】Spring Boot實現SSE實時推送實戰

以下是一個完整的基于 Spring Boot 的 Server-Sent Events (SSE) 示例&#xff0c;包括服務端和客戶端的實現。 一、服務端實現 1. 創建 Spring Boot 項目 首先&#xff0c;創建一個基本的 Spring Boot 項目&#xff0c;并添加 spring-boot-starter-web 依賴。在 pom.xml 中…

若依導出模板時設置動態excel下拉框(表連接的)

若依導出模板時設置動態excel下拉框&#xff08;表連接的&#xff09; 一、問題二、解決1、實體類2.1、臨時使用2.2、統一工具類3、調用 一、問題 若依導出只能&#xff1b;使用dictType、combo、comboReadDict、readConverterExp這些來控制字典的導出下拉&#xff0c;如果不是…

Rabbitmq集成springboot 使用死信隊列

一、何為死信隊列 RabbitMQ的死信隊列&#xff08;Dead Letter Queue&#xff0c;DLQ&#xff09;是一種特殊的隊列機制&#xff0c;用于處理那些無法被正常消費的消息。這些消息可能由于各種原因無法被消費者正確處理&#xff0c;如果不加以處理&#xff0c;可能會導致隊列堵塞…

Spring Boot 項目中 resources 文件讀取

開發必備&#xff01;Spring Boot 項目中 resources 文件讀取的 9 大方案詳解 在 Spring Boot 項目中&#xff0c;resources 目錄承載著大量的關鍵資源&#xff0c;如配置文件、模板文件、腳本資源、數據文件等。而如何以合適的方式高效、安全地讀取這些資源&#xff0c;往往是…

力扣-1143.最長公共子序列

題目描述 給定兩個字符串 text1 和 text2&#xff0c;返回這兩個字符串的最長 公共子序列 的長度。如果不存在 公共子序列 &#xff0c;返回 0 。 一個字符串的 子序列 是指這樣一個新的字符串&#xff1a;它是由原字符串在不改變字符的相對順序的情況下刪除某些字符&#xf…