背景介绍

在若依框架目前的实现中,是把图片存储到了服务器本地的目录,通过服务进行访问,这样做存储的是比较省事,但是缺点也有很多:

  • 硬件与网络要求:服务器通常需要高性能的硬件和稳定的网络环境,以保证文件传输的效率和稳定性。这可能会增加硬件和网络资源的成本和维护难度。
  • 管理难度:服务器目录需要管理员进行配置和管理,包括权限设置、备份策略等。如果管理不善或配置不当,可能会引发一些安全问题和性能问题。
  • 性能瓶颈:如果服务器处理能力不足或网络带宽不够,可能会导致性能瓶颈,影响文件上传、下载和访问的速度。
  • 单点故障风险:服务器故障可能导致所有存储在其上的文件无法访问,尽管可以通过备份和冗余措施来降低这种风险,但单点故障的风险仍然存在。

基于以上原因,企业中很多的文件都会存储到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作为分布式对象存储服务,提供了高可用、高扩展性的文件存储解决方案,能够有效解决传统本地存储在硬件成本、管理复杂度、性能瓶颈和单点故障等方面的问题,特别适合企业级应用的文件存储需求。

如果文章对你有帮助,不妨点个赞!谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88739.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88739.shtml
英文地址,请注明出处:http://en.pswp.cn/web/88739.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac如何连接惠普M126a打印机(教程篇)

这里写自定义目录标题Mac如何连接惠普M126a打印机&#xff08;教程篇&#xff09;教程配置如下&#xff1a;Mac如何连接惠普M126a打印机&#xff08;教程篇&#xff09; 惠普M126a连接Mac&#xff08;教程篇&#xff09; 教程配置如下&#xff1a; 首先&#xff0c;先获取与HP打…

感恩日记:记录生活中的美好时刻

感恩日记的landing page登录注册填写感恩事项私信可以体验一下

一扇门铃,万向感应——用 eventfd 实现零延迟通信

&#x1f50d; 本篇概要 eventfd 是 Linux 提供的一种轻量级事件通知机制。你可以把它想象成一个“计数器盒子”。它里面维护的是一个64位的计数器。写入&#xff1a;往盒子里放一些数字&#xff08;比如 1、5、10&#xff09;&#xff0c;表示有几件事发生了。读取&#xff1a…

基于Node.js的线上教学系统的设计与实现(源码+论文+调试+安装+售后)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。系统背景近年来&#xff0c;全球数字化浪潮的推进与教育公平化需求的增长&#xff0c;促使线上教学迎…

互斥锁详解(操作系统os)

1. 互斥锁 (Mutex) - 档案室的“智能锁”首先&#xff0c;我们给之前讨论的那些“锁”一个正式的名字&#xff1a;互斥锁 (Mutex)。概念&#xff1a;你可以把它简单理解成档案室门上的一把“智能锁”。它只有两种状态&#xff1a;locked (已上锁) 或 unlocked (未上锁)。操作&a…

自动润滑系统:从 “盲目养护“ 到智能精注的工业运维革命

​在工业运维的漫长历史中&#xff0c;传统润滑模式如同"定时喂饭"——无论设备实际需求&#xff0c;仅凭经验或固定周期执行润滑作业。这种模式埋下两大隐患&#xff1a;过度润滑&#xff1a;某汽车生产线曾因季度性强制润滑&#xff0c;每年浪费1.2吨润滑脂&#x…

【Java八股文总结 — 包学会】(二)计算机网络

1.一条url输入到浏览器最后显示页面的过程 URL解析与处理 浏览器解析URL&#xff08;如https://www.example.com/page&#xff09; 分离协议&#xff08;https&#xff09;、域名&#xff08;www.example.com&#xff09;和资源路径&#xff08;/page&#xff09; 检查HSTS预加…

力扣61.旋转链表

给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。示例 1&#xff1a;输入&#xff1a;head [1,2,3,4,5], k 2 输出&#xff1a;[4,5,1,2,3]示例 2&#xff1a;输入&#xff1a;head [0,1,2], k 4 输出&#xff1a;[2,0,1]提示…

深度剖析:std::vector 内存机制与 push_back 扩容策略

深度剖析&#xff1a;std::vector 内存机制与 push_back 扩容策略 1. std::vector 核心内部结构 #mermaid-svg-8HOj3MqsD6UVgEeA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-8HOj3MqsD6UVgEeA .error-icon{fill:…

GROW领导力模型

GROW领导力模型是由英国教练格雷厄姆亚历山大&#xff08;Graham Alexander&#xff09;、艾伦Fine和约翰惠特默&#xff08;John Whitmore&#xff09;在20世纪80年代提出的&#xff0c;最初用于体育教练领域&#xff0c;后来被广泛应用于企业管理、领导力发展和个人成长中。它…

打破并发瓶颈:虚拟线程实现详解与传统线程模型的性能对比

目录 一、定义与特性 二、虚拟线程实现 2.1 使用 Thread.startVirtualThread() 创建 2.2 使用 Thread.ofVirtual() 创建 2.3 使用 ThreadFactory 创建 2.4 使用 Executors.newVirtualThreadPerTaskExecutor()创建 三、虚拟线程和普通线程的区别 3.1 线程管理方式不同 3…

“28项评测23项SOTA——GLM-4.1V-9B-Thinking本地部署教程:10B级视觉语言模型的性能天花板!

一、模型介绍 GLM-4.1V-9B-Thinking是由智谱AI联合清华大学团队推出的多模态大模型&#xff0c;以GLM-4-9B-0414基座模型为底&#xff0c;通过引入“思维链推理机制”和“课程采样强化学习策略”&#xff08;Reinforcement Learning with Curriculum Sampling&#xff09;&…

推荐系统-Random算法

Random算法总结引言 在推荐系统研究与应用中&#xff0c;我们常常需要一些简单的基线算法来衡量更复杂算法的性能提升。Random&#xff08;随机推荐&#xff09;算法是最基础的基线方法之一&#xff0c;它通过随机生成评分来模拟用户对物品的偏好。虽然这种方法看似简单&#x…

Django--02模型和管理站点

Django–02模型与站点管理 Part 2: Models and the admin site 本教程承接Django–01的内容。我们将设置数据库、创建你的第一个模型&#xff0c;并快速了解 Django 自动生成的管理站点。 文章目录Django--02模型与站点管理前言一、设置数据库1.1 参考文档链接1.2 默认设置1.3…

CS课程项目设计1:交互友好的井字棋游戏

最近突然想开设一个专栏了&#xff0c;专门为计算机专业的同行分享一些入门级的课程项目设计&#xff0c;旨在让同学更好地了解CS项目的设计流程&#xff0c;同时给出代码来介绍coding过程。 今天要分享的是第一个CS课程项目&#xff1a;交互友好的井字棋游戏。 1. 研究目的 井…

首个自动驾驶VLA综述介绍

当视觉(Vision)、语言(Language)和行动(Action)三大能力在一个模型中融合,自动驾驶的未来将走向何方? 近日,来自麦吉尔大学、清华大学、小米公司和威斯康辛麦迪逊的研究团队联合发布了全球首篇针对自动驾驶领域的视觉-语言-行动(Vision-Language-Action, VLA)模型的…

C# 接口(接口可以继承接口)

接口可以继承接口 之前我们已经知道接口实现可以从基类被继承&#xff0c;而接口本身也可以从一个或多个接口继承而来。要指定某个接口继承其他的接口&#xff0c;应在接口声明中把基接口名称以逗号分隔的列表形式 放在接口名称后面的冒号之后&#xff0c;如下所示。类在基类列…

linux----------------------线程同步与互斥(上)

1.线程互斥 1-1 进程线程间的互斥相关背景概念 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源 临界区&#xff1a;每个线程内部访问临界资源的代码就叫做临界区 互斥&#xff1a;任何时刻&#xff0c;互斥保证只有一个执行进入临界区&#xff0c;对临界资源起…

百度AI的开放新篇章:文心4.5本地化部署指南与未来生态战略展望

百度AI的开放新篇章&#xff1a;文心4.5本地化部署指南与未来生态战略展望 一起来玩转文心大模型吧&#x1f449;文心大模型免费下载地址&#xff1a;https://ai.gitcode.com/theme/1939325484087291906 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30…

笔记/sklearn中的数据划分方法

文章目录一、前言二、数据划分方法1. 留出法&#xff08;Hold-out&#xff09;2. K折交叉验证&#xff08;K-Fold&#xff09;3. 留一法&#xff08;Leave-One-Out&#xff09;三、总结一、前言 简要介绍数据划分在机器学习中的作用。 二、数据划分方法 1. 留出法&#xff0…