SpringBoot使用阿里oss實現(xiàn)文件上傳的流程步驟
一、準(zhǔn)備
1.介紹
阿里云是阿里巴巴集團旗下全球領(lǐng)先的云計算公司,也是國內(nèi)最大的云服務(wù)提供商 。

云服務(wù)指的就是通過互聯(lián)網(wǎng)對外提供的各種各樣的服務(wù),比如像:語音服務(wù)、短信服務(wù)、郵件服務(wù)、視頻直播服務(wù)、文字識別服務(wù)、對象存儲服務(wù)等等。
當(dāng)我們在項目開發(fā)時需要用到某個或某些服務(wù),就不需要自己來開發(fā)了,可以直接使用阿里云提供好的這些現(xiàn)成服務(wù)就可以了。比如:在項目開發(fā)當(dāng)中,我們要實現(xiàn)一個短信發(fā)送的功能,如果我們項目組自己實現(xiàn),將會非常繁瑣,因為你需要和各個運營商進(jìn)行對接。而此時阿里云完成了和三大運營商對接,并對外提供了一個短信服務(wù)。我們項目組只需要調(diào)用阿里云提供的短信服務(wù),就可以很方便的來發(fā)送短信了。這樣就降低了我們項目的開發(fā)難度,同時也提高了項目的開發(fā)效率。(大白話:別人幫我們實現(xiàn)好了功能,我們只要調(diào)用即可)
云服務(wù)提供商給我們提供的軟件服務(wù)通常是需要收取一部分費用的。
阿里云對象存儲OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云存儲服務(wù)。使用OSS,您可以通過網(wǎng)絡(luò)隨時存儲和調(diào)用包括文本、圖片、音頻和視頻等在內(nèi)的各種文件。

在我們使用了阿里云OSS對象存儲服務(wù)之后,我們的項目當(dāng)中如果涉及到文件上傳這樣的業(yè)務(wù),在前端進(jìn)行文件上傳并請求到服務(wù)端時,在服務(wù)器本地磁盤當(dāng)中就不需要再來存儲文件了。我們直接將接收到的文件上傳到oss,由 oss幫我們存儲和管理,同時阿里云的oss存儲服務(wù)還保障了我們所存儲內(nèi)容的安全可靠。

2.開通云服務(wù)
在開通云服務(wù)前,我們需要自己注冊并登錄阿里云。
2.1.通過控制臺找到對象存儲OSS服務(wù)

選擇要開通的服務(wù)

如果是第一次訪問,還需要開通對象存儲服務(wù)OSS

2.2.創(chuàng)建一個Bucket
開通OSS服務(wù)之后,就可以進(jìn)入到阿里云對象存儲的控制臺,開通OSS服務(wù)之后,就可以進(jìn)入到阿里云對象存儲的控制臺

輸入Bucket的相關(guān)信息

其他的信息,配置項使用默認(rèn)的即可。
2.3. 配置AccessKey
2.3.1 創(chuàng)建
點擊 "AccessKey管理",進(jìn)入到管理頁面。

點擊 "創(chuàng)建AccessKey"


2.3.2. 配置
以管理員身份打開CMD命令行,執(zhí)行如下命令,配置系統(tǒng)的環(huán)境變量。
set OSS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx set OSS_ACCESS_KEY_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
注意:將上述的ACCESS_KEY_ID 與 ACCESS_KEY_SECRET 的值一定要替換成自己的 。
執(zhí)行如下命令,讓更改生效。
setx OSS_ACCESS_KEY_ID "%OSS_ACCESS_KEY_ID%" setx OSS_ACCESS_KEY_SECRET "%OSS_ACCESS_KEY_SECRET%"
執(zhí)行如下命令,驗證環(huán)境變量是否生效。
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
二、項目實現(xiàn)
1、導(dǎo)入依賴

具體導(dǎo)入依賴包 可以去官網(wǎng)查看:OSS Java SDK兼容性和示例代碼_對象存儲(OSS)-阿里云幫助中心
<!--阿里云OSS依賴-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.4</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>2、使用案例
將官方提供的入門程序,復(fù)制過來,將里面的參數(shù)值改造成我們自己的即可。代碼如下:
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.nio.file.Files;
public class Demo {
public static void main(String[] args) throws Exception {
// Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
String endpoint = "https://oss-cn-beijing.aliyuncs.com";
// 從環(huán)境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫B(tài)ucket名稱,例如examplebucket。
String bucketName = "java-ai";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "001.jpg";
// 填寫B(tài)ucket所在地域。以華東1(杭州)為例,Region填寫為cn-hangzhou。
String region = "cn-beijing";
// 創(chuàng)建OSSClient實例。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
File file = new File("C:\\Users\\deng\\Pictures\\1.jpg");
byte[] content = Files.readAllBytes(file.toPath());
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
} 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();
}
}
}
}需要將上面的 endpoint ,bucketName,objectName,file 都需要改成自己的。
- endpoint:阿里云OSS中的bucket對應(yīng)的域名
- bucketName:Bucket名稱
- objectName:對象名稱,在Bucket中存儲的對象的名稱
- region:bucket所屬區(qū)域

運行demo,沒有報錯。我們就可以去對應(yīng)的bucket下查看文件是否上傳成功

3、實際使用
3.1.編寫阿里云OSS上傳文件工具類(由官方的示例代碼改造而來)
官網(wǎng)上文件的操作還有很多的案例代碼,感興趣的可以自己去看一下

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
@Component
public class AliyunOSSOperator {
private String endpoint = "https://oss-cn-beijing.aliyuncs.com";
private String bucketName = "java-ai";
private String region = "cn-beijing";
public String upload(byte[] content, String originalFilename) throws Exception {
// 從環(huán)境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫Object完整路徑,例如202406/1.png。Object完整路徑中不能包含Bucket名稱。
//獲取當(dāng)前系統(tǒng)日期的字符串,格式為 yyyy/MM
String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
//生成一個新的不重復(fù)的文件名
String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
String objectName = dir + "/" + newFileName;
// 創(chuàng)建OSSClient實例。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
} finally {
ossClient.shutdown();
}
return endpoint.split("http://")[0] + "http://" + bucketName + "." + endpoint.split("http://")[1] + "/" + objectName;
}
}3.2. 實現(xiàn)UploadController代碼
import com.itheima.pojo.Result;
import com.itheima.utils.AliyunOSSOperator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.UUID;
@Slf4j
@RestController
public class UploadController {
@Autowired
private AliyunOSSOperator aliyunOSSOperator;
@PostMapping("/upload")
public Result upload(MultipartFile file) throws Exception {
log.info("上傳文件:{}", file);
if (!file.isEmpty()) {
// 生成唯一文件名
String originalFilename = file.getOriginalFilename();
String extName = originalFilename.substring(originalFilename.lastIndexOf("."));
String uniqueFileName = UUID.randomUUID().toString().replace("-", "") + extName;
// 上傳文件
String url = aliyunOSSOperator.upload(file.getBytes(), uniqueFileName);
return Result.success(url);
}
return Result.error("上傳失敗");
}
}3.3.3 配置阿里云oss(可選)
在AliyunOSS操作的工具類中,我們直接將 endpoint、bucketName參數(shù)直接在java文件中寫死了。對于這些容易變動的參數(shù),我們可以將其配置在配置文件中,然后通過從yml文件中讀取外部配置的屬性。
具體實現(xiàn)代碼如下:
1.添加AliyunOss配置到application.yml
#阿里云OSS
aliyun:
oss:
endpoint: https://oss-cn-beijing.aliyuncs.com
bucketName: java-ai
region: cn-beijing2.修改AliyunOSSOperator代碼
方式一:@Value注解
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
@Component
public class AliyunOSSOperator {
//方式一: 通過@Value注解一個屬性一個屬性的注入
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.oss.bucketName}")
private String bucketName;
@Value("${aliyun.oss.region}")
private String region;
public String upload(byte[] content, String originalFilename) throws Exception {
// 從環(huán)境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫Object完整路徑,例如2024/06/1.png。Object完整路徑中不能包含Bucket名稱。
//獲取當(dāng)前系統(tǒng)日期的字符串,格式為 yyyy/MM
String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
//生成一個新的不重復(fù)的文件名
String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
String objectName = dir + "/" + newFileName;
// 創(chuàng)建OSSClient實例。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
} finally {
ossClient.shutdown();
}
return endpoint.split("http://")[0] + "http://" + bucketName + "." + endpoint.split("http://")[1] + "/" + objectName;
}
}方式二: 編寫對應(yīng)配置類
如果只有一兩個屬性需要注入,而且不需要考慮復(fù)用性,使用@Value注解就可以了。
但是使用@Value注解注入配置文件的配置項,如果配置項多,注入繁瑣,不便于維護管理 和 復(fù)用。我們可以直接將配置文件中配置項的值自動的注入到對象的屬性中簡化這些配置參數(shù)的注入。
實現(xiàn)步驟:
1). 需要創(chuàng)建一個實現(xiàn)類,且實體類中的屬性名和配置文件當(dāng)中key的名字必須要一致
比如:配置文件當(dāng)中叫endpoint,實體類當(dāng)中的屬性也得叫endpoint,另外實體類當(dāng)中的屬性還需要提供 getter / setter方法
2). 需要將實體類交給Spring的IOC容器管理,成為IOC容器當(dāng)中的bean對象
3). 在實體類上添加@ConfigurationProperties注解,并通過perfect屬性來指定配置參數(shù)項的前綴
具體實現(xiàn)步驟:
1). 定義實體類AliyunOSSProperties ,并交給IOC容器管理
配置類中的屬性名相同,Spring會幫我們自動映射。yml中屬性的命名如果兩個單詞之間采用橫線連接Spring也會映射到對應(yīng)駝峰命名的字段上。比如:yml中的屬性為bucket-name或bucketName會映射到對應(yīng)配置類中的bucketName上。

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliyunOSSProperties {
private String endpoint;
private String bucketName;
private String region;
}2). 修改AliyunOSSOperator
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
@Component
public class AliyunOSSOperator {
//方式一: 通過@Value注解一個屬性一個屬性的注入
//@Value("${aliyun.oss.endpoint}")
//private String endpoint;
//@Value("${aliyun.oss.bucketName}")
//private String bucketName;
//@Value("${aliyun.oss.region}")
//private String region;
@Autowired
private AliyunOSSProperties aliyunOSSProperties;
public String upload(byte[] content, String originalFilename) throws Exception {
String endpoint = aliyunOSSProperties.getEndpoint();
String bucketName = aliyunOSSProperties.getBucketName();
String region = aliyunOSSProperties.getRegion();
// 從環(huán)境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫Object完整路徑,例如2024/06/1.png。Object完整路徑中不能包含Bucket名稱。
//獲取當(dāng)前系統(tǒng)日期的字符串,格式為 yyyy/MM
String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
//生成一個新的不重復(fù)的文件名
String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
String objectName = dir + "/" + newFileName;
// 創(chuàng)建OSSClient實例。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
} finally {
ossClient.shutdown();
}
return endpoint.split("http://")[0] + "http://" + bucketName + "." + endpoint.split("http://")[1] + "/" + objectName;
}
}以上就是SpringBoot使用阿里oss實現(xiàn)文件上傳的流程步驟的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot 阿里oss文件上傳的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決dubbo啟動報服務(wù)注冊失敗Failed?to?register?dubbo
這篇文章主要介紹了解決dubbo啟動報服務(wù)注冊失敗Failed?to?register?dubbo問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
java中char對應(yīng)的ASCII碼的轉(zhuǎn)化操作
這篇文章主要介紹了java中char對應(yīng)的ASCII碼的轉(zhuǎn)化操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
IntelliJ?IDEA?2023.2最新版激活方法及驗證ja-netfilter配置是否成功
隨著2023.2版本的發(fā)布,用戶們渴望了解如何激活這個最新版的IDE,本文將介紹三種可行的激活方案,包括許可證服務(wù)器、許可證代碼和idea?vmoptions配置,幫助讀者成功激活并充分利用IDEA的功能,感興趣的朋友參考下吧2023-08-08
Springboot 2.x集成kafka 2.2.0的示例代碼
kafka近幾年更新非??欤部梢钥闯鰇afka在企業(yè)中是用的頻率越來越高。本文主要為大家介紹了Springboot 2.x集成kafka 2.2.0的示例代碼,需要的可以參考一下2022-04-04
Springboot任務(wù)之異步任務(wù)的使用詳解
今天學(xué)習(xí)了一個新技能SpringBoot實現(xiàn)異步任務(wù),所以特地整理了本篇文章,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
Mybatis?Plus使用XML編寫動態(tài)sql的超簡易方法
這篇文章主要介紹了Mybatis?Plus使用XML編寫動態(tài)sql的超簡易方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
獲取系統(tǒng)參數(shù)System.getProperties()與配置文件參數(shù)@Value(“${key}“)
這篇文章主要介紹了獲取系統(tǒng)參數(shù)System.getProperties()與配置文件參數(shù)@Value("${key}"),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05

