【第4期】Springboot集成阿里云对象存储OSS+Vue+Iview文件上传组件

本期简介

文件上传是非常常见的功能,本期要实现的功能是将文件存储到阿里云分布式对象存储OSS中,这样做的好处是随便哪里都可以方便的展示出该图片,并且图片以链接形式在客户端浏览器渲染,流量不会经过后台,降低后台压力,但若对文件有限制性的操作,还是要通过后台返回文件

  • 本期要点:
  1. 配置阿里云OSS密钥
  2. 编写OSS上传的简单类
  3. Springboot集成OSS
  4. 后端开发上传接口
  5. 前端开发Vue+Iview+Uploader组件
  6. 前端渲染上传后的图片

一、配置阿里云OSS密钥及桶

1、购买链接

如果没有云存储,可访问阿里云官网,搜索对象存储或者访问下方链接,按需购买
https://common-buy.aliyun.com/?spm=5176.7933691.J_5253785160.2.64e62c47OY978E&commodityCode=oss_rc_dp_cn

2、创建桶

对象存储是以桶来进行文件管理,文件都存在一个个的桶里,每个桶可以存放目录和文件,即可以按照文件进行分类存储,可以创建多个桶。
在这里插入图片描述

从下图可以看到,一个桶里面可以存储多个文件夹,文件夹里可以存多个文件,桶里面也可以直接存文件
在这里插入图片描述

二、配置密钥

要想将文件上传到OSS中,用的是AK/SK的方式进行认证授权,所以需要先在阿里云OSS中配置安全密钥,

  • 点击头像打开访问控制页面
    在这里插入图片描述

  • 创建用户
    在这里插入图片描述

  • 创建访问AccessKey
    需要注意的是,创建的时候AppSecret及时复制出来保存,关闭弹窗后,无法再从阿里云页面找到,若不慎丢失,需重新生成
    在这里插入图片描述
    至此,云存储已经具备了,访问的AK/SK也有了,接下来编写客户端上传下载的逻辑。

三、编写OSS上传的简单类

1、将AK、SK配置到环境变量

在这里插入图片描述

2、添加maven依赖

        <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version></dependency>

3、初始化OSS配置

  • 配置类
public class OssConfig {private String accessKeyId;private String secretAccessKey;private String endpoint;private String bucketName;
}
  • 初始化OSS
private final DefaultCredentialProvider credentialsProvider;private final OssConfig ossConfig;@SneakyThrowspublic OssHelper(@Autowired OssConfig ossConfig) {// 从环境变量中获取访问凭证。运行本代码示例之前,请先配置环境变量。if (ossConfig == null) {throw new ServerException("初始化对象存储工具失败,配置信息未读取到");}this.ossConfig = ossConfig;this.credentialsProvider = CredentialsProviderFactory.newDefaultCredentialProvider(ossConfig.getAccessKeyId(), ossConfig.getSecretAccessKey());}

3、上传方法

OSS支持上传的类型非常多,这里例举几类

  • 上传本地二进制文件
public Optional<String> upload(File file, String ossDir, String ossFileName) {try {return this.uploadToOss(file, ossDir, ossFileName);} catch (Exception exception) {log.error("上传字符串前异常:{}", exception.getMessage());}return Optional.empty();}
  • 上传文本
    public Optional<String> upload(String content, String ossDir, String ossFileName) {try {InputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));return this.uploadToOss(inputStream, ossDir, ossFileName);} catch (Exception exception) {log.error("上传字符串前异常:{}", exception.getMessage());}return Optional.empty();}
  • 上传字节类
    public Optional<String> upload(byte[] content, String ossDir, String ossFileName) {try {InputStream inputStream = new ByteArrayInputStream(content);return this.uploadToOss(inputStream, ossDir, ossFileName);} catch (Exception exception) {log.error("上传字符串前异常:{}", exception.getMessage());}return Optional.empty();}
  • 上传网络资源
    public Optional<String> upload(URL url, String ossDir, String ossFileName) {try {if (url == null) {return Optional.empty();}InputStream inputStream = url.openStream();return this.uploadToOss(inputStream, ossDir, ossFileName);} catch (Exception exception) {log.error("上传字符串前异常:{}", exception.getMessage());}return Optional.empty();}
  • 上传核心业务逻辑
    private Optional<String> uploadToOss(Object object, String ossDir, String ossFileName) {// 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), credentialsProvider);try {String objectName = getObjectName(ossDir, ossFileName);PutObjectRequest putObjectRequest = null;if (object instanceof InputStream) {putObjectRequest = new PutObjectRequest(ossConfig.getBucketName(), objectName, (InputStream) object);}if (object instanceof File) {putObjectRequest = new PutObjectRequest(ossConfig.getBucketName(), objectName, (InputStream) object);}if (putObjectRequest == null) {return Optional.empty();}PutObjectResult result = ossClient.putObject(putObjectRequest);// 设置签名URL过期时间,单位为毫秒。本示例以设置过期时间为50年为例。Date expiration = new Date(new Date().getTime() + 50 * 365 * 24 * 3600 * 1000L);// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。URL url = ossClient.generatePresignedUrl(ossConfig.getBucketName(), objectName, expiration);if (url != null) {return Optional.of(url.toString());}return Optional.empty();} catch (OSSException oe) {log.error("Caught an OSSException, which means your request made it to OSS, "+ "but was rejected with an error response for some reason.");log.error("Error Message:" + oe.getErrorMessage());log.error("Error Code:" + oe.getErrorCode());log.error("Request ID:" + oe.getRequestId());log.error("Host ID:" + oe.getHostId());} catch (ClientException ce) {log.error("Caught an ClientException, which means the client encountered "+ "a serious internal problem while trying to communicate with OSS, "+ "such as not being able to access the network.");log.error("Error Message:" + ce.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}return Optional.empty();}

4、测试上传与验证

从下图可以看到,成功把字符串hello world上传到了OSS的certificate目录下,文件名为test.txt
在这里插入图片描述

查看OSS桶的对应文件内容,与上传一致
在这里插入图片描述

5、下载方法

public void download(String ossDir, String ossFileName) {String objectName = getObjectName(ossDir, ossFileName);// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), credentialsProvider);try {// 调用ossClient.getObject返回一个OSSObject实例,该实例包含文件内容及文件元信息。OSSObject ossObject = ossClient.getObject(ossConfig.getBucketName(), objectName);// 调用ossObject.getObjectContent获取文件输入流,可读取此输入流获取其内容。InputStream content = ossObject.getObjectContent();if (content != null) {BufferedReader reader = new BufferedReader(new InputStreamReader(content));while (true) {String line = reader.readLine();if (line == null) {break;}System.out.println("\n" + line);}// 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。content.close();}} catch (OSSException oe) {System.out.println("Caught an OSSException, which means your request made it to OSS, "+ "but was rejected with an error response for some reason.");System.out.println("Error Message:" + oe.getErrorMessage());System.out.println("Error Code:" + oe.getErrorCode());System.out.println("Request ID:" + oe.getRequestId());System.out.println("Host ID:" + oe.getHostId());} catch (ClientException ce) {System.out.println("Caught an ClientException, which means the client encountered "+ "a serious internal problem while trying to communicate with OSS, "+ "such as not being able to access the network.");System.out.println("Error Message:" + ce.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}}

6、测试下载与验证

从OSS中将前面上传的test.txt下载下来打印出内容,与上传时的一致
在这里插入图片描述

四、springboot集成OSS

到了这一步,上传、下载等功能已经具备了,只需要将其与Springboot集成起来,即可在各个业务中使用,为了使用单例模式,这里将其注册为Spring Bean

1、配置类

@Data
@Configuration
@ConfigurationProperties(prefix = "aliyun.oss")
public class OssConfig {private String accessKeyId;private String secretAccessKey;private String endpoint;private String bucketName;
}

2、application.yml配置

在这里插入图片描述

3、OSS核心类

@Slf4j
@Component
public class OssHelper {private final DefaultCredentialProvider credentialsProvider;private final OssConfig ossConfig;@SneakyThrowspublic OssHelper(@Autowired OssConfig ossConfig) {// 从环境变量中获取访问凭证。运行本代码示例之前,请先配置环境变量。if (ossConfig == null) {throw new ServerException("初始化对象存储工具失败,配置信息未读取到");}this.ossConfig = ossConfig;this.credentialsProvider = CredentialsProviderFactory.newDefaultCredentialProvider(ossConfig.getAccessKeyId(), ossConfig.getSecretAccessKey());}public Optional<String> upload(File file, String ossDir, String ossFileName) {.........}public Optional<String> upload(String content, String ossDir, String ossFileName) {...........}public Optional<String> upload(byte[] content, String ossDir, String ossFileName) {............}public Optional<String> upload(URL url, String ossDir, String ossFileName) {............}private Optional<String> uploadToOss(Object object, String ossDir, String ossFileName) {............}public void download(String ossDir, String ossFileName) {............}
}

五、后端开发上传逻辑

1、编写接口,入参只有一个MultipartFile

在这里插入图片描述

2、上传逻辑

这里是直接获取到MultipartFile的字节数组,将其上传到OSStest/cover目录下,文件名是通过雪花算法生成的id
在这里插入图片描述
至此,后端已经具备文件上传的完整功能,接下来编写前端的上传功能

六、前端开发Vue+Iview+Uploader组件

1、使用Iview Uploader

该组件可以支持拖拽和选择上传,功能方便,实现简单

          <FormItem label="封面" prop="coverId"><Uploadref="upload":show-upload-list="false":format="['zip','png','jpg','jpeg','pdf','doc','docx','ppt','pptx','xls','xlsx']":max-size="5120":on-success="handleUploadSuccess":on-error="handleUploadFailed":on-format-error="handleFormatError":on-exceeded-size="handleMaxSize":before-upload="handleBeforeUpload"style="width: 210px;height:50px;"type="drag":action="albumCoverAction":headers="uploadHeader"><div><Icon type="ios-cloud-upload" size="30" style="color: #3399ff"></Icon><p>点击上传或将图片拖拽到这里</p></div></Upload><RadioGroup v-model="formData.coverId"><Row style="margin-top: 40px;margin-left: 0px;"><Col span="4"><div><Card dis-hover style="height:auto;width:210px;"><p slot="title">自定义封面</p><Row><Col span="24"><Radio :label="customCover.id"><div :class="selectedCover===customCover.id?'album-cover-selected':'album-cover'"@click="changeCover(customCover)"style="margin-right: 10px;"><img :src="customCover.coverUrl"/></div></Radio></Col></Row></Card></div></Col><Col span="19" offset="1"><Card dis-hover style="height:auto"><p slot="title">系统默认封面</p><Row><Col span="24"><Radio v-for="(item, index) in $store.state.defaultAlbumCovers" class="cover-default":key="index":label="item.id"><div :class="selectedCover===item.id?'album-cover-selected':'album-cover'"@click="changeCover(item)"style="margin-right: 5px;"><img :src="item.coverUrl"/></div></Radio></Col></Row></Card></Col></Row></RadioGroup></FormItem>

2、上传地址和鉴权

上面的上传组件中的文件往哪里上传,以及怎么通过后端的用户登录认证,是通过如下2个值来决定的
在这里插入图片描述

七、前端渲染上传后的图片

在这里插入图片描述

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

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

相关文章

数据库——创建存储过程、函数和触发器安装phpmyadmin

1.实验内容及原理 1. 在 Windows 系统中安装 VMWare 虚拟机&#xff0c;在 VMWare 中安装 Ubuntu 系统,并在 Ubuntu 中搭建 LAMP 实验环境。 2. 使用 MySQL 进行一些基本操作&#xff1a; &#xff08;1&#xff09;登录 MySQL&#xff0c;在 MySQL 中创建用户&#xff0c;…

【CCF-B】院士主编,通过率70%,国人友好,审稿慢

01 期刊概况 Frontiers of Computer Science 【出版社】Springer&#xff0c; Co-publication with Higher Education Press 【ISSN】2095-2228 【ISSN】2095-2236 【检索情况】SCI&EI双检 【WOS收录年份】2012年 【期刊官网】 https://www.springer.com/journal/11…

C# WPF上位机开发(Web API联调)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 很多时候&#xff0c;客户需要开发的不仅仅是一个上位机系统&#xff0c;它还有其他很多配套的系统或设备&#xff0c;比如物流小车、立库、数字孪…

JavaScript中实现页面跳转的几种常用方法

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍在JavaScript中实现页面跳转的几种常用方法以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学习记录获&#xff0c;友友们有任何问题…

JavaScript基础知识点总结:从零开始学习JavaScript(六)

本章内容主要让小伙伴们自主练习 &#xff0c;建议大家先自己写出来答案&#xff0c;然后对照我的&#xff01;&#xff08;题不难主要培养自己的编程思维&#xff01;&#xff01;&#xff01;&#xff09; 如果大家感感兴趣也可以去看&#xff1a; &#x1f389;博客主页&…

ssm基于VUE的图书馆管理系统的设计与实现论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#x…

uniapp中uview组件库丰富的Calendar 日历用法

目录 基本使用 #日历模式 #单个日期模式 #多个日期模式 #日期范围模式 #自定义主题颜色 #自定义文案 #日期最大范围 #是否显示农历 #默认日期 基本使用 通过show绑定一个布尔变量用于打开或收起日历弹窗。通过mode参数指定选择日期模式&#xff0c;包含单选/多选/范围…

Ubuntu安装FSearch

文章目录 简介安装配置Fsearch的搜索路径参考资料 简介 Fsearch是Ubuntu等Linux系统中用于文件快速搜索的软件&#xff0c;类似于Windows系统中的Everything。下面介绍如何在Ubuntu系统中安装并使用Fsearch&#xff0c;只需简单几步&#xff01;&#x1f3c3;&#x1f3c3; 安…

机器学习归一化和标准化

1. 为什么做归一化和标准化 样本中有多个特征&#xff0c;每一个特征都有自己的定义域和取值范围&#xff0c;他们对距离计算也是不同的&#xff0c;如取值较大的影响力会盖过取值较小的参数。因此&#xff0c;为了公平&#xff0c;样本参数必须做一些归一化处理&#xff0c;将…

如何批量删除文件名中的空格?

如何批量删除文件名中的空格&#xff1f;这个操作适合适合什么样的场景呢&#xff1f;相信大家都有过从网上下载文件的经历&#xff0c;我们会发现很多下载的文件名称里面会包含一些空格&#xff0c;如果文件名称的空格太多的话就会对阅读造成一定的影响&#xff0c;最好的办法…

Ajax学习

文章目录 AjaxAjax 是什么Ajax 经典应用场景Ajax 原理示意图ajax的异步请求的方法ajax的逻辑:应用实例-验证用户名是否存在思路框架图:需求分析: 到数据库去验证用户名是否可用思路框架图大功告成:使用JQuery-Ajax实现上面相同的需求:Ajax Ajax 是什么 AJAX 即"Async…

Vue3-31-路由-RouterView的name属性的作用

作用描述 <router-view> 标签是用来渲染路由对应的组件的位置&#xff1b; 默认情况下&#xff0c;一个路由是只对应一个组件的。 但是&#xff0c;可以通过给 <router-view> 指定 name 属性的方式&#xff0c;实现同时渲染多个组件的效果。 这也叫做 命名视图。 注…