SpringBoot使用阿里oss實(shí)現(xiàn)文件上傳的流程步驟
一、準(zhǔn)備
1.介紹
阿里云是阿里巴巴集團(tuán)旗下全球領(lǐng)先的云計(jì)算公司,也是國(guó)內(nèi)最大的云服務(wù)提供商 。
云服務(wù)指的就是通過(guò)互聯(lián)網(wǎng)對(duì)外提供的各種各樣的服務(wù),比如像:語(yǔ)音服務(wù)、短信服務(wù)、郵件服務(wù)、視頻直播服務(wù)、文字識(shí)別服務(wù)、對(duì)象存儲(chǔ)服務(wù)等等。
當(dāng)我們?cè)陧?xiàng)目開(kāi)發(fā)時(shí)需要用到某個(gè)或某些服務(wù),就不需要自己來(lái)開(kāi)發(fā)了,可以直接使用阿里云提供好的這些現(xiàn)成服務(wù)就可以了。比如:在項(xiàng)目開(kāi)發(fā)當(dāng)中,我們要實(shí)現(xiàn)一個(gè)短信發(fā)送的功能,如果我們項(xiàng)目組自己實(shí)現(xiàn),將會(huì)非常繁瑣,因?yàn)槟阈枰透鱾€(gè)運(yùn)營(yíng)商進(jìn)行對(duì)接。而此時(shí)阿里云完成了和三大運(yùn)營(yíng)商對(duì)接,并對(duì)外提供了一個(gè)短信服務(wù)。我們項(xiàng)目組只需要調(diào)用阿里云提供的短信服務(wù),就可以很方便的來(lái)發(fā)送短信了。這樣就降低了我們項(xiàng)目的開(kāi)發(fā)難度,同時(shí)也提高了項(xiàng)目的開(kāi)發(fā)效率。(大白話:別人幫我們實(shí)現(xiàn)好了功能,我們只要調(diào)用即可)
云服務(wù)提供商給我們提供的軟件服務(wù)通常是需要收取一部分費(fèi)用的。
阿里云對(duì)象存儲(chǔ)OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云存儲(chǔ)服務(wù)。使用OSS,您可以通過(guò)網(wǎng)絡(luò)隨時(shí)存儲(chǔ)和調(diào)用包括文本、圖片、音頻和視頻等在內(nèi)的各種文件。
在我們使用了阿里云OSS對(duì)象存儲(chǔ)服務(wù)之后,我們的項(xiàng)目當(dāng)中如果涉及到文件上傳這樣的業(yè)務(wù),在前端進(jìn)行文件上傳并請(qǐng)求到服務(wù)端時(shí),在服務(wù)器本地磁盤(pán)當(dāng)中就不需要再來(lái)存儲(chǔ)文件了。我們直接將接收到的文件上傳到oss,由 oss幫我們存儲(chǔ)和管理,同時(shí)阿里云的oss存儲(chǔ)服務(wù)還保障了我們所存儲(chǔ)內(nèi)容的安全可靠。
2.開(kāi)通云服務(wù)
在開(kāi)通云服務(wù)前,我們需要自己注冊(cè)并登錄阿里云。
2.1.通過(guò)控制臺(tái)找到對(duì)象存儲(chǔ)OSS服務(wù)
選擇要開(kāi)通的服務(wù)
如果是第一次訪問(wèn),還需要開(kāi)通對(duì)象存儲(chǔ)服務(wù)OSS
2.2.創(chuàng)建一個(gè)Bucket
開(kāi)通OSS服務(wù)之后,就可以進(jìn)入到阿里云對(duì)象存儲(chǔ)的控制臺(tái),開(kāi)通OSS服務(wù)之后,就可以進(jìn)入到阿里云對(duì)象存儲(chǔ)的控制臺(tái)
輸入Bucket的相關(guān)信息
其他的信息,配置項(xiàng)使用默認(rèn)的即可。
2.3. 配置AccessKey
2.3.1 創(chuàng)建
點(diǎn)擊 "AccessKey管理",進(jìn)入到管理頁(yè)面。
點(diǎn)擊 "創(chuàng)建AccessKey"
2.3.2. 配置
以管理員身份打開(kāi)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í)行如下命令,驗(yàn)證環(huán)境變量是否生效。
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
二、項(xiàng)目實(shí)現(xiàn)
1、導(dǎo)入依賴(lài)
具體導(dǎo)入依賴(lài)包 可以去官網(wǎng)查看:OSS Java SDK兼容性和示例代碼_對(duì)象存儲(chǔ)(OSS)-阿里云幫助中心
<!--阿里云OSS依賴(lài)--> <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、使用案例
將官方提供的入門(mén)程序,復(fù)制過(guò)來(lái),將里面的參數(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請(qǐng)按實(shí)際情況填寫(xiě)。 String endpoint = "https://oss-cn-beijing.aliyuncs.com"; // 從環(huán)境變量中獲取訪問(wèn)憑證。運(yùn)行本代碼示例之前,請(qǐng)確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填寫(xiě)B(tài)ucket名稱(chēng),例如examplebucket。 String bucketName = "java-ai"; // 填寫(xiě)Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱(chēng)。 String objectName = "001.jpg"; // 填寫(xiě)B(tài)ucket所在地域。以華東1(杭州)為例,Region填寫(xiě)為cn-hangzhou。 String region = "cn-beijing"; // 創(chuàng)建OSSClient實(shí)例。 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對(duì)應(yīng)的域名
- bucketName:Bucket名稱(chēng)
- objectName:對(duì)象名稱(chēng),在Bucket中存儲(chǔ)的對(duì)象的名稱(chēng)
- region:bucket所屬區(qū)域
運(yùn)行demo,沒(méi)有報(bào)錯(cuò)。我們就可以去對(duì)應(yīng)的bucket下查看文件是否上傳成功
3、實(shí)際使用
3.1.編寫(xiě)阿里云OSS上傳文件工具類(lèi)(由官方的示例代碼改造而來(lái))
官網(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)境變量中獲取訪問(wèn)憑證。運(yùn)行本代碼示例之前,請(qǐng)確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填寫(xiě)Object完整路徑,例如202406/1.png。Object完整路徑中不能包含Bucket名稱(chēng)。 //獲取當(dāng)前系統(tǒng)日期的字符串,格式為 yyyy/MM String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM")); //生成一個(gè)新的不重復(fù)的文件名 String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf(".")); String objectName = dir + "/" + newFileName; // 創(chuàng)建OSSClient實(shí)例。 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. 實(shí)現(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操作的工具類(lèi)中,我們直接將 endpoint、bucketName參數(shù)直接在java文件中寫(xiě)死了。對(duì)于這些容易變動(dòng)的參數(shù),我們可以將其配置在配置文件中,然后通過(guò)從yml文件中讀取外部配置的屬性。
具體實(shí)現(xiàn)代碼如下:
1.添加AliyunOss配置到application.yml
#阿里云OSS aliyun: oss: endpoint: https://oss-cn-beijing.aliyuncs.com bucketName: java-ai region: cn-beijing
2.修改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 { //方式一: 通過(guò)@Value注解一個(gè)屬性一個(gè)屬性的注入 @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)境變量中獲取訪問(wèn)憑證。運(yùn)行本代碼示例之前,請(qǐng)確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填寫(xiě)Object完整路徑,例如2024/06/1.png。Object完整路徑中不能包含Bucket名稱(chēng)。 //獲取當(dāng)前系統(tǒng)日期的字符串,格式為 yyyy/MM String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM")); //生成一個(gè)新的不重復(fù)的文件名 String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf(".")); String objectName = dir + "/" + newFileName; // 創(chuàng)建OSSClient實(shí)例。 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; } }
方式二: 編寫(xiě)對(duì)應(yīng)配置類(lèi)
如果只有一兩個(gè)屬性需要注入,而且不需要考慮復(fù)用性,使用@Value
注解就可以了。
但是使用@Value注解注入配置文件的配置項(xiàng),如果配置項(xiàng)多,注入繁瑣,不便于維護(hù)管理 和 復(fù)用。我們可以直接將配置文件中配置項(xiàng)的值自動(dòng)的注入到對(duì)象的屬性中簡(jiǎn)化這些配置參數(shù)的注入。
實(shí)現(xiàn)步驟:
1). 需要?jiǎng)?chuàng)建一個(gè)實(shí)現(xiàn)類(lèi),且實(shí)體類(lèi)中的屬性名和配置文件當(dāng)中key的名字必須要一致
比如:配置文件當(dāng)中叫endpoint,實(shí)體類(lèi)當(dāng)中的屬性也得叫endpoint,另外實(shí)體類(lèi)當(dāng)中的屬性還需要提供 getter / setter方法
2). 需要將實(shí)體類(lèi)交給Spring的IOC容器管理,成為IOC容器當(dāng)中的bean對(duì)象
3). 在實(shí)體類(lèi)上添加@ConfigurationProperties
注解,并通過(guò)perfect屬性來(lái)指定配置參數(shù)項(xiàng)的前綴
具體實(shí)現(xiàn)步驟:
1). 定義實(shí)體類(lèi)AliyunOSSProperties ,并交給IOC容器管理
配置類(lèi)中的屬性名相同,Spring會(huì)幫我們自動(dòng)映射。yml中屬性的命名如果兩個(gè)單詞之間采用橫線連接Spring也會(huì)映射到對(duì)應(yīng)駝峰命名的字段上。比如:yml中的屬性為bucket-name或bucketName會(huì)映射到對(duì)應(yīng)配置類(lèi)中的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 { //方式一: 通過(guò)@Value注解一個(gè)屬性一個(gè)屬性的注入 //@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)境變量中獲取訪問(wèn)憑證。運(yùn)行本代碼示例之前,請(qǐng)確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填寫(xiě)Object完整路徑,例如2024/06/1.png。Object完整路徑中不能包含Bucket名稱(chēng)。 //獲取當(dāng)前系統(tǒng)日期的字符串,格式為 yyyy/MM String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM")); //生成一個(gè)新的不重復(fù)的文件名 String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf(".")); String objectName = dir + "/" + newFileName; // 創(chuàng)建OSSClient實(shí)例。 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實(shí)現(xiàn)文件上傳的流程步驟的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot 阿里oss文件上傳的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決dubbo啟動(dòng)報(bào)服務(wù)注冊(cè)失敗Failed?to?register?dubbo
這篇文章主要介紹了解決dubbo啟動(dòng)報(bào)服務(wù)注冊(cè)失敗Failed?to?register?dubbo問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12java中char對(duì)應(yīng)的ASCII碼的轉(zhuǎn)化操作
這篇文章主要介紹了java中char對(duì)應(yīng)的ASCII碼的轉(zhuǎn)化操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08IntelliJ?IDEA?2023.2最新版激活方法及驗(yàn)證ja-netfilter配置是否成功
隨著2023.2版本的發(fā)布,用戶(hù)們渴望了解如何激活這個(gè)最新版的IDE,本文將介紹三種可行的激活方案,包括許可證服務(wù)器、許可證代碼和idea?vmoptions配置,幫助讀者成功激活并充分利用IDEA的功能,感興趣的朋友參考下吧2023-08-08Springboot 2.x集成kafka 2.2.0的示例代碼
kafka近幾年更新非常快,也可以看出kafka在企業(yè)中是用的頻率越來(lái)越高。本文主要為大家介紹了Springboot 2.x集成kafka 2.2.0的示例代碼,需要的可以參考一下2022-04-04Springboot任務(wù)之異步任務(wù)的使用詳解
今天學(xué)習(xí)了一個(gè)新技能SpringBoot實(shí)現(xiàn)異步任務(wù),所以特地整理了本篇文章,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06Mybatis?Plus使用XML編寫(xiě)動(dòng)態(tài)sql的超簡(jiǎn)易方法
這篇文章主要介紹了Mybatis?Plus使用XML編寫(xiě)動(dòng)態(tài)sql的超簡(jiǎn)易方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01獲取系統(tǒng)參數(shù)System.getProperties()與配置文件參數(shù)@Value(“${key}“)
這篇文章主要介紹了獲取系統(tǒng)參數(shù)System.getProperties()與配置文件參數(shù)@Value("${key}"),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05