背景介紹
在若依框架目前的實現中,是把圖片存儲到了服務器本地的目錄,通過服務進行訪問,這樣做存儲的是比較省事,但是缺點也有很多:
- 硬件與網絡要求:服務器通常需要高性能的硬件和穩定的網絡環境,以保證文件傳輸的效率和穩定性。這可能會增加硬件和網絡資源的成本和維護難度。
- 管理難度:服務器目錄需要管理員進行配置和管理,包括權限設置、備份策略等。如果管理不善或配置不當,可能會引發一些安全問題和性能問題。
- 性能瓶頸:如果服務器處理能力不足或網絡帶寬不夠,可能會導致性能瓶頸,影響文件上傳、下載和訪問的速度。
- 單點故障風險:服務器故障可能導致所有存儲在其上的文件無法訪問,盡管可以通過備份和冗余措施來降低這種風險,但單點故障的風險仍然存在。
基于以上原因,企業中很多的文件都會存儲到OSS中,OSS可以解決以上所有的問題,并且成本也不高,下面我就把阿里的OSS集成到若依項目中(MinIO 存儲應該同樣可以試用)
。
依賴配置
在項目的pom.xml
文件中添加必要的依賴:
<properties><aliyun.sdk.oss>3.10.2</aliyun.sdk.oss><lombok.version>1.18.22</lombok.version>
</properties><!-- 依賴聲明 -->
<dependencyManagement><dependencies><!-- 其他依賴省略... --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>${aliyun.sdk.oss}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency></dependencies>
</dependencyManagement>
技術實現
改造目標
主要是要對controller.common.CommonController.uploadFile
下的@PostMapping("/upload") public AjaxResult uploadFile(MultipartFile file)
來進行改造。
1. 文件存儲服務類
創建OSS文件存儲服務,封裝上傳和刪除操作:
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.zzyl.oss.properties.AliOssConfigProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;@Slf4j
@Component
public class OSSAliyunFileStorageService {@AutowiredOSS ossClient;@AutowiredAliOssConfigProperties aliOssConfigProperties;/*** 上傳文件* @param objectName 文件名* @param inputStream 文件流對象* @return*/public String store(String objectName, InputStream inputStream) {//文件讀取路徑String url = null;// 判斷文件if (inputStream == null) {log.error("上傳文件:objectName{}文件流為空", objectName);return url;}log.info("OSS文件上傳開始:{}", objectName);try {String bucketName = aliOssConfigProperties.getBucketName();// 上傳文件PutObjectRequest request = new PutObjectRequest(bucketName, objectName, inputStream);PutObjectResult result = ossClient.putObject(request);// 設置權限(公開讀)ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);if (result != null) {log.info("OSS文件上傳成功:{}", objectName);}} catch (OSSException oe) {log.error("OSS文件上傳錯誤:{}", oe);} catch (ClientException ce) {log.error("OSS文件上傳客戶端錯誤:{}", ce);}//文件訪問路徑規則 https://BucketName.Endpoint/ObjectNameStringBuilder stringBuilder = new StringBuilder("https://");stringBuilder.append(aliOssConfigProperties.getBucketName()).append(".").append(aliOssConfigProperties.getEndpoint()).append("/").append(objectName);return stringBuilder.toString();}/*** 根據url刪除文件* @param pathUrl url地址(全路徑)*/public void delete(String pathUrl) {String prefix = "https://"+aliOssConfigProperties.getBucketName()+"."+ aliOssConfigProperties.getEndpoint()+"/";String key = pathUrl.replace(prefix, "");List<String> keys = new ArrayList<>();keys.add(key);// 刪除ObjectsossClient.deleteObjects(new DeleteObjectsRequest(aliOssConfigProperties.getBucketName()).withKeys(keys));}}
2. OSS客戶端配置類
創建OSS客戶端的自動配置,實現客戶端初始化和存儲桶管理:
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.SetBucketLoggingRequest;
import com.zzyl.oss.properties.AliOssConfigProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Slf4j
@Configuration
public class OssAliyunAutoConfig {@AutowiredAliOssConfigProperties aliOssConfigProperties;@Beanpublic OSS ossClient(){log.info("-----------------開始創建OSSClient--------------------");OSS ossClient = new OSSClientBuilder().build(aliOssConfigProperties.getEndpoint(),aliOssConfigProperties.getAccessKeyId(), aliOssConfigProperties.getAccessKeySecret());//判斷容器是否存在,不存在就創建if (!ossClient.doesBucketExist(aliOssConfigProperties.getBucketName())) {ossClient.createBucket(aliOssConfigProperties.getBucketName());CreateBucketRequest createBucketRequest = new CreateBucketRequest(aliOssConfigProperties.getBucketName());//設置問公共可讀createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);ossClient.createBucket(createBucketRequest);}//添加客戶端訪問日志SetBucketLoggingRequest request = new SetBucketLoggingRequest(aliOssConfigProperties.getBucketName());// 設置存放日志文件的存儲空間。request.setTargetBucket(aliOssConfigProperties.getBucketName());// 設置日志文件存放的目錄。request.setTargetPrefix(aliOssConfigProperties.getBucketName());ossClient.setBucketLogging(request);log.info("-----------------結束創建OSSClient--------------------");return ossClient;}}
3. 配置屬性類
創建OSS配置屬性類,用于管理阿里云OSS的連接參數:
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;/*** @ClassName AliOssConfigProperties.java* */
@Setter
@Getter
@NoArgsConstructor
@ToString
@Configuration
@ConfigurationProperties(prefix = "oss")
public class AliOssConfigProperties {/*** 域名站點*/private String endpoint ;/*** 秘鑰Id*/private String accessKeyId ;/*** 秘鑰*/private String accessKeySecret ;/*** 桶名稱*/private String bucketName ;}
應用配置
在application.yml
中添加OSS相關配置:
oss:endpoint: oss-cn-hangzhou.aliyuncs.comaccessKeyId: your-access-key-idaccessKeySecret: your-access-key-secretbucketName: your-bucket-name
控制器改造
在原有的CommonController中注入OSS服務,并修改uploadFile方法:
@Autowired
private OSSAliyunFileStorageService ossFileStorageService;@PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file) {try {// 生成唯一文件名String objectName = generateObjectName(file.getOriginalFilename());// 上傳到OSSString url = ossFileStorageService.store(objectName, file.getInputStream());return AjaxResult.success().put("url", url);} catch (Exception e) {return AjaxResult.error("上傳失敗");}
}
測試使用
OSS作為分布式對象存儲服務,提供了高可用、高擴展性的文件存儲解決方案,能夠有效解決傳統本地存儲在硬件成本、管理復雜度、性能瓶頸和單點故障等方面的問題,特別適合企業級應用的文件存儲需求。
如果文章對你有幫助,不妨點個贊!謝謝!