若依框架集成阿里云OSS实现文件上传优化
背景介绍
在若依框架目前的实现中,是把图片存储到了服务器本地的目录,通过服务进行访问,这样做存储的是比较省事,但是缺点也有很多:
- 硬件与网络要求:服务器通常需要高性能的硬件和稳定的网络环境,以保证文件传输的效率和稳定性。这可能会增加硬件和网络资源的成本和维护难度。
- 管理难度:服务器目录需要管理员进行配置和管理,包括权限设置、备份策略等。如果管理不善或配置不当,可能会引发一些安全问题和性能问题。
- 性能瓶颈:如果服务器处理能力不足或网络带宽不够,可能会导致性能瓶颈,影响文件上传、下载和访问的速度。
- 单点故障风险:服务器故障可能导致所有存储在其上的文件无法访问,尽管可以通过备份和冗余措施来降低这种风险,但单点故障的风险仍然存在。
基于以上原因,企业中很多的文件都会存储到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作为分布式对象存储服务,提供了高可用、高扩展性的文件存储解决方案,能够有效解决传统本地存储在硬件成本、管理复杂度、性能瓶颈和单点故障等方面的问题,特别适合企业级应用的文件存储需求。
如果文章对你有帮助,不妨点个赞!谢谢!