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