最近因为项目中需要存储很多的图片,不想存储到服务器上,因此就直接选用阿里云的对象服务(Object Storage Service,简称 OSS)来进行存储,本文将介绍 Spring Boot 集成 OSS 的一个完整过程。

那么 OSS 是什么呢?

简而言之,OSS 是一种海量、安全、低成本、高可靠的云存储服务。

关于 OSS 的知识就不再这里赘述了,大家可以自行学习下。

开通 OSS

首先需要在阿里云控制台开通 OSS,然后需要创建存储空间(Bucket),我这里命名为 wupx-img

如果之前没有创建过 AccessKey,鼠标移到右上角的账号后点击 AccessKey 管理,然后创建就可以了。

或者直接输入 https://ak-console.aliyun.com/#/ 来进行密钥的创建和查看。

准备工作做好后,就开始进行项目实战吧!

Spring Boot 集成 OSS

Spring Boot 集成 OSS 主要分为以下三步:

  1. 加入 OSS 依赖
  2. 配置 OSS
  3. 演示 OSS 基本操作

加入依赖

首先创建一个 Spring Boot 项目,然后在 pom.xml 加入如下依赖集成 OSS:

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

创建 OSS 配置

在配置文件 application.properties 中配置 OSS 的相关参数,具体内容如下:

#访问OSS的域名
aliyun.endpoint=http://oss-cn-beijing.aliyuncs.com
aliyun.accessKeyId=yourAccessKeyId
aliyun.accessKeySecret=yourAccessKeySecret
#管理所存储Object的存储空间名称
#aliyun.bucketName=yourBucketName
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.max-file-size=10MB

其中指定了 OSS 的访问域名、密钥以及存储空间 Bucket 的名称等。

然后在 config 包下创建 OSSConfiguration 类,会从配置文件中读取到对应的参数,并且把 ossClient 单例化。

@Configuration
@Component
public class OSSConfiguration { private volatile static OSS ossClient; private volatile static OSSClientBuilder ossClientBuilder; private static String endpoint; private static String accessKeyId; private static String accessKeySecret; @Value("${aliyun.bucketName}")
private String bucketName; @Value("${aliyun.endpoint}")
public void setEndpoint(String endpoint) {
OSSConfiguration.endpoint = endpoint;
} @Value("${aliyun.accessKeyId}")
public void setAccessKeyId(String accessKeyId) {
OSSConfiguration.accessKeyId = accessKeyId;
} @Value("${aliyun.accessKeySecret}")
public void setAccessKeySecret(String accessKeySecret) {
OSSConfiguration.accessKeySecret = accessKeySecret;
} public String getBucketName() {
return bucketName;
} @Bean
@Scope("prototype")
public static OSS initOSSClient() {
if (ossClient == null) {
synchronized (OSSConfiguration.class) {
if (ossClient == null) {
ossClient = initOSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
}
}
}
return ossClient;
} public static OSSClientBuilder initOSSClientBuilder() {
if (ossClientBuilder == null) {
synchronized (OSSConfiguration.class) {
if (ossClientBuilder == null) {
ossClientBuilder = new OSSClientBuilder();
}
}
}
return ossClientBuilder;
}
}

服务类

在这里主要介绍 OSS 的上传、下载、删除、查看 URL 等简单操作,在 service 包下创建 OSSService 类,然后注入 ossClientossConfiguration

上传文件

首先来看下如何上传文件,首先通过 UUID 生成文件名,防止重复,再创建一个 ObjectMetadata,可以设置用户自定义的元数据以及 HTTP 头,比如内容长度,ETag 等,最后通过调用 ossClientputObject 方法来完成文件上传,并返回文件名,具体代码如下所示:

public String uploadFile(MultipartFile file, String storagePath) {
String fileName = "";
try {
fileName = UUID.randomUUID().toString();
InputStream inputStream = file.getInputStream();
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(inputStream.available());
objectMetadata.setCacheControl("no-cache");
objectMetadata.setHeader("Pragma", "no-cache");
objectMetadata.setContentType(file.getContentType());
objectMetadata.setContentDisposition("inline;filename=" + fileName);
fileName = storagePath + "/" + fileName;
// 上传文件
ossClient.putObject(ossConfiguration.getBucketName(), fileName, inputStream, objectMetadata);
} catch (IOException e) {
log.error("Error occurred: {}", e.getMessage(), e);
}
return fileName;
}

编写对应的 Controller 层,调用上传文件接口后,在文件管理中可以看到文件已经上传成功了:

获取文件列表

可以通过 ListObjectsRequest 构建请求参数,比如设置 Bucket 名称和列举文件的最大个数,然后调用 ossClientlistObjects 方法就可以获取到 objectListing,再获取文件的元信息,最后将文件名称返回,具体代码如下:

public List<String> listObjects() {
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(ossConfiguration.getBucketName()).withMaxKeys(200);
ObjectListing objectListing = ossClient.listObjects(listObjectsRequest);
List<OSSObjectSummary> objectSummaries = objectListing.getObjectSummaries();
return objectSummaries.stream().map(OSSObjectSummary::getKey).collect(Collectors.toList());
}

判断文件是否存在

判断文件是否存在,直接通过 ossClientdoesObjectExist 方法就可以进行判断,传入的参数为 Bucket 名称和文件名称,具体代码如下:

public boolean doesObjectExist(String fileName) {
try {
if (Strings.isEmpty(fileName)) {
log.error("文件名不能为空");
return false;
} else {
return ossClient.doesObjectExist(ossConfiguration.getBucketName(), fileName);
}
} catch (OSSException | ClientException e) {
e.printStackTrace();
}
return false;
}

下载文件

下载存储在 OSS 的文件,首先需要传入 Bucket 名称和文件名称调用 ossClientgetObject 方法获取 ossObjectossObject 包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流,然后调用 ossObjectgetObjectContent 方法获取输入流,然后进行文件的下载,具体代码如下:

public void exportFile(OutputStream os, String objectName) {
OSSObject ossObject = ossClient.getObject(ossConfiguration.getBucketName(), objectName);
// 读取文件内容
BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
BufferedOutputStream out = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
int lenght;
try {
while ((lenght = in.read(buffer)) != -1) {
out.write(buffer, 0, lenght);
}
out.flush();
} catch (IOException e) {
log.error("Error occurred: {}", e.getMessage(), e);
}
}

删除文件

删除文件也比较简单,直接调用 deleteObject 方法,传入对应的 Bucket 名称和文件名称即可,具体代码如下:

public void deleteFile(String fileName) {
try {
ossClient.deleteObject(ossConfiguration.getBucketName(), fileName);
} catch (Exception e) {
log.error("Error occurred: {}", e.getMessage(), e);
}
}

查看 URL

获取文件的访问地址可以调用 ossClientgeneratePresignedUrl,在调用的时候还需要设置过期时间,具体代码如下:

public String getSingeNatureUrl(String filename, int expSeconds) {
Date expiration = new Date(System.currentTimeMillis() + expSeconds * 1000);
URL url = ossClient.generatePresignedUrl(ossConfiguration.getBucketName(), filename, expiration);
if (url != null) {
return url.toString();
}
return null;
}

通过调用接口即可返回文件对应的 url 地址,我们通过 url 就可以访问图片,效果如下:

到此为止,OSS 的基本操作就简单介绍完了,大家可以多动手试试,不会的可以看下官方的帮助文档。

跨域规则

阿里云 OSS 解决请求跨越问题:进入对应的 Bucket,然后依次点击权限管理->跨越设置->创建规则,然后填写上对应的规则,具体如下图所示:

总结

本文的完整代码在 https://github.com/wupeixuan/SpringBoot-Learnoss 目录下。

Spring Boot 结合 OSS 还是比较简单的,大家可以下载项目源码,自己在本地运行调试这个项目,更好地理解如何在 Spring Boot 中构建基于 OSS 的应用。

最好的关系就是互相成就,大家的点赞、在看、分享、留言就是我创作的最大动力。

参考

https://github.com/wupeixuan/SpringBoot-Learn

https://help.aliyun.com/document_detail/32008.html

Spring Boot 集成阿里云 OSS 进行文件存储的更多相关文章

  1. spring boot集成阿里云短信发送接收短信回复功能

    1.集成阿里云通信发送短信: 在pom.xml文件里添加依赖 <!--阿里短信服务--> <dependency> <groupId>com.aliyun</ ...

  2. 玩转spring boot——结合阿里云持续交付

    前言 在互联网项目中,项目测试.部署往往需要花费大量时间.传统方式是在本地打包.测试完毕程序,然后通过ftp上传至服务器,再把测试的配置文件修改为生产环境的配置文件,最后重新运行服务.这一过程如果交给 ...

  3. 阿里云OSS同城冗余存储技术解析

    一.背景 近年来,面对数字化转型带来的挑战,越来越多的企业开始将关键业务系统上云,也有更多的业务创新在云上,帮助企业实现业务增长,这些数据已经成为企业最重要的资产.资源.对于企业来说,如何确保宝贵的数 ...

  4. 阿里云 oss 小文件上传进度显示

    对阿里云OSS上传小文件时的进度,想过两个方法:一是.通过多线程监測Inputstream剩余的字节数来计算,可是由于Inputstream在两个线程中共用,假设上传线程将Inputstream关闭, ...

  5. wget下载阿里云oss的文件报错403

    问题 在实际工作中,我们为了方便,会将一些脚本储存在云端(阿里云OSS),这样方便我们使用和下载,但是在实际的使用过程中,我们会遇到一些问题. 示例链接:https://djxlsp.oss-cn-s ...

  6. JAVA整合阿里云OSS实现文件上传功能

    引入maven <dependency> <groupId>org.apache.commons</groupId> <artifactId>commo ...

  7. 云-阿里云-OSS:对象存储 OSS

    ylbtech-云-阿里云-OSS:对象存储 OSS 对象存储服务(Object Storage Service,OSS)是一种海量.安全.低成本.高可靠的云存储服务,适合存放任意类型的文件.容量和处 ...

  8. 阿里云OSS同城冗余存储正式商业化,提供云上同城容灾能力

    近日,阿里云正式发布OSS同城冗余存储产品.这是国内目前提供同城多AZ冗余部署能力覆盖最广的云上对象存储产品,可以实现云存储的同城双活,满足企业级客户对于“发生机房级灾难事件时数据不丢失,业务不中断” ...

  9. Sping Boot入门到实战之实战篇(一):实现自定义Spring Boot Starter——阿里云消息队列服务Starter

    在 Sping Boot入门到实战之入门篇(四):Spring Boot自动化配置 这篇中,我们知道Spring Boot自动化配置的实现,主要由如下几部分完成: @EnableAutoConfigu ...

随机推荐

  1. Vue CLI Webpack 创建Vue项目

    简介 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手,还 ...

  2. Qt之先用了再说系列-多线程方式1

    Qt 多线程的用法还是比较简单的,也比较好用,接下来我们就分析分析如何使用. 说起Qt 线程的使用方式,一般有2种使用方式,具体哪种比较好看自己心情了,现在有官方的推荐用法,用不用还是看你心情的 好, ...

  3. golang 中的struct理解

    golang实验代码 package main import("fmt") type Stu struct{ name string age int } func (stu *St ...

  4. ubuntu18.04配置与美化

    一:初步系统配置 1 不可或缺的更新 如果在上一步中勾选了安装 Ubuntu 时下载更新,那么大部分的系统更新已经下载完毕. 不过为了确保,先移步到 设置→详细信息 ,点击右下角的 检查更新 ,如果存 ...

  5. POJ2806 Square

    题目描述 给定\(2*1\)和\(2 * 2\)两种规格的地砖,请问\(2 * n\)的地面总共有多少种方法? 下面是铺满\(2*17\)的地面的示意图. 输入输出格式 输入 多组数据,每组数据包括1 ...

  6. 解决QT5移植报错:This application failed to start because no Qt platform plugin could be initialized

    今天自己基于Pyqt5开发了一个软件,打包成exe后在自己的电脑上运行正常,在其他机器上提示: This application failed to start because no Qt platf ...

  7. 分析dubbo心跳检测机制

    目的: 维持provider和consumer之间的长连接 实现: dubbo心跳时间heartbeat默认是60s,超过heartbeat时间没有收到消息,就发送心跳消息(provider,cons ...

  8. C++ Templates (1.7 总结 Summary)

    返回完整目录 目录 1.7 总结 Summary 1.7 总结 Summary 函数模板定义了一系列不同模板实参的函数 当传递实参给依赖于模板参数的函数参数,函数模板推断模板参数并实例化相应的参数类型 ...

  9. 初识ABP vNext(5):ABP扩展实体

    Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 扩展实体 路由整理 最后 前言 上一篇实现了前端vue部分的用户登录和菜单权限控制,但是有一些问题需要解决,比如用户头 ...

  10. Vscode配置C++环境

    (终于申请博客了qaq) 之前用了那么久Dev-C++,总算换了一个编辑器,Visual Studio Code (Vscode). 界面可比以前的舒适多了. Vscode作为一款功能极其丰富的开发工 ...