目录
- 前言
- 一、阿里云oss简介
- 二、使用步骤
- 1.引入依赖
- 3.完整依赖
- 4.yml配置文件
- 5.配置类代码
- 6.工具类代码
- 7.控制类
- 8.postmen请求调用
- 总结:
- 拓展:
前言
技术不断革新,优胜略汰,不断努力成长是为长远计。
一、阿里云oss简介
阿里云的oss对象存储是新型的云存储工具,详细介绍请参考oss介绍注:oss相关名词如endpoint、accessKeyId、bucketName等后面扩展中会作简略描述,详细了解可自行百度也可去官网查看API。
二、使用步骤
开发环境:
JDK版本:1.8
maven版本:3.9.0
开发工具:IDEA社区版ideaIC-2018.3
项目框架:spring boot 版本为 2.6.3 springboot搭建传送门
1.引入依赖
pom中添加阿里云oss的依赖
<!-- aliyun-oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.16.0</version>
</dependency>
3.完整依赖
完整pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>oss_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--SpringBoot启动依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.6.3</version>
<scope>test</scope>
</dependency>
<!-- aliyun-oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.16.0</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<!-- fastjson -->
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>fastjson</artifactId>-->
<!-- <version>2.0.23</version>-->
<!-- </dependency>-->
</dependencies>
</project>
注:不知道哪里用到了lombok注解,但不用lombok注解就会报下面这个错,所以还是添上了
[ErrorCode]: SocketException
[RequestId]: Unknown
4.yml配置文件
application.yml
server:
port: 8088
aliyun:
oss:
endpoint: oss-cn-shanghai.aliyuncs.com
accessKeyId: uU2e3lsseG9KDEDGDERDFSFADSDFDExdsdse
accessKeySecret: DJFLDasdljEDldld8lDE34ldrd8
注:这里配置的endpoint/accessKeyId/accessKeySecret参数均为随机输入,无效,请根据自己的oss替换掉对应参数(如何在oss中查看这几个参数请参考阿里云官网文档)。
5.配置类代码
OssConfig.java
package com.oss.config;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @ClassDescription: 通过value注解将参数从yml配置文件中读取过来,创建为bean在方法中调用
* @Author:李白
* @Date:2023/3/6 16:13
*/
@Configuration
public class OssConfig {
@Value("${aliyun.oss.endpoint}")
public String endpoint;
@Value("${aliyun.oss.accessKeyId}")
public String accessKeyId;
@Value("${aliyun.oss.accessKeySecret}")
public String accessKeySecret;
@Bean
public OSS oss(){
return new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
}
}
6.工具类代码
包含了多种存取数据方法
OssUtil.java
package com.oss.utils;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.*;
/**
* @ClassDescription: 操作oss数据存取等的工具类
* @Author:李白
* @Date:2023/3/6 16:18
*/
@Component
public class OssUtil {
/**
* 此处的oss是将配置文件中的参数配置后生成bean,通过自动注入来获取配置参数后的对象oss
*/
@Autowired
private OSS oss;
/**
* 为了能在每个方法中使用配置号参数的oss对象,需要将其静态化,如果oss被static修饰,则每次调用时oss都是空,所以这里需要做一下转换
* 通过postConstruct注解将oss转为静态的ossP,这样在每次调用时都是配置好的参数的一个oss对象
* @PostConstruct是Java自带的注解,在方法上加该注解会在项目启动的时候执行该方法,也可以理解为在spring容器初始化的时候执行该方法。
* @postConstruct可以修饰一个非静态的void方法,使用场景为:在生成对象时想完成某些初始化操作,初始化又依赖于自动注入,构造方法中无法实现时
* 使用此注解修饰一个方法来实现初始化操作,注解的方法会在自动注入完成后被调用-----执行顺序--》construct构造函数-》@Autowired自动注入-》@PostConstruct
*/
private static OSS ossP;
/**
* 默认的oss桶位置
*/
public static final String fixedBucket = "bucketName-123";
@PostConstruct
public void ossTransfer(){
//该方法会在上面的依赖注入后自动被调用
ossP = oss;
}
/**
* 上传字符串
* @param objectName oss文件全路径名-默认是桶位置加全路径名,如桶位置为ossbucket,全路径名为upload/string/str.json,则数据会放到ossbucket下的upload/string包中,文件名为str.json
* @param content 上传内容
*/
public static void uploadString(String objectName, String content){
PutObjectRequest putObjectRequest = new PutObjectRequest(fixedBucket, objectName, new ByteArrayInputStream(content.getBytes()));
ossP.putObject(putObjectRequest);
}
/**
* 上传字符串
* @param bucketName 文件存在oss的桶名称
* @param objectName 文件在oss中的全路径
* @param content 上传内容
*/
public static void uploadString(String bucketName, String objectName, String content){
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
ossP.putObject(putObjectRequest);
}
/**
* 上传文件
* @param objectName 文件在oss中的全路径
* @param filePath 上传文件的本地路径
*/
public static void uploadFile(String objectName, String filePath){
PutObjectRequest putObjectRequest = new PutObjectRequest(fixedBucket, objectName, new File(filePath));
ossP.putObject(putObjectRequest);
}
/**
* 上传文件
* @param bucketName 文件所在oss桶名称
* @param objectName 文件在oss中的全路径
* @param filePath 上传文件的本地路径
*/
public static void uploadFile(String bucketName, String objectName, String filePath){
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath));
ossP.putObject(putObjectRequest);
}
/**
* 上传multi文件
* @param objectName 文件全路径
* @param multipartFile 上传的文件
*/
public static void uploadMultipartFile(String objectName, MultipartFile multipartFile){
byte[] bytes = new byte[0];
try {
bytes = multipartFile.getBytes();
} catch (IOException e) {
throw new RuntimeException(e);
}
InputStream inputStream = new ByteArrayInputStream(bytes);
PutObjectRequest putObjectRequest = new PutObjectRequest(fixedBucket, objectName, inputStream);
ossP.putObject(putObjectRequest);
}
/**
* multi方式上传文件
* @param bucketName oss中桶名称
* @param objectName 文件在oss中的全路径
* @param multipartFile 上传的文件
*/
public static void uploadMultipartFile(String bucketName, String objectName, MultipartFile multipartFile){
byte[] bytes = new byte[0];
try {
bytes = multipartFile.getBytes();
} catch (IOException e) {
throw new RuntimeException(e);
}
InputStream inputStream = new ByteArrayInputStream(bytes);
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
ossP.putObject(putObjectRequest);
}
/**
* 上传流数据
* @param objectName 数据在oss中的全路径
* @param inputStream 流数据内容
*/
public static void uploadStream(String objectName, InputStream inputStream){
PutObjectRequest putObjectRequest = new PutObjectRequest(fixedBucket, objectName, inputStream);
ossP.putObject(putObjectRequest);
}
/**
* 上传流数据
* @param bucketName oss桶名称
* @param objectName 数据所在oss中的全路径
* @param inputStream 流数据
*/
public static void uploadStream(String bucketName, String objectName, InputStream inputStream){
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
ossP.putObject(putObjectRequest);
}
/**
* 下载字符串数据
* @param objectName 数据所在oss的全路径
* @return 字符串
* @throws IOException
*/
public static String downloadString(String objectName) throws IOException {
OSSObject ossObject = ossP.getObject(fixedBucket, objectName);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
StringBuilder stringBuilder = new StringBuilder();
while (true){
String line = bufferedReader.readLine();
if(line==null){
break;
}else {
stringBuilder.append(line);
}
}
bufferedReader.close();
return stringBuilder.toString();
}
/**
* 下载字符串数据
* @param bucketName oss桶位置
* @param objectName 数据所在oss中的全路径
* @return 返回字符串
* @throws IOException
*/
public static String downloadString(String bucketName, String objectName) throws IOException {
OSSObject ossObject = ossP.getObject(bucketName, objectName);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
StringBuilder stringBuilder = new StringBuilder();
while (true){
String line = bufferedReader.readLine();
if(line==null){
break;
}else {
stringBuilder.append(line);
}
}
bufferedReader.close();
return stringBuilder.toString();
}
/**
* 下载文件
* @param objectName 数据所在oss全路径
* @param fileName 文件名
*/
public static void downloadFile(String objectName, String fileName){
ossP.getObject(new GetObjectRequest(fixedBucket, objectName),new File(fileName));
}
/**
* 下载文件
* @param bucketName 文件所在oss桶名称
* @param objectName 文件所在oss中的全路径
* @param fileName 文件名
*/
public static void downloadFile(String bucketName, String objectName, String fileName){
ossP.getObject(new GetObjectRequest(bucketName, objectName),new File(fileName));
}
/**
* 删除数据
* @param objectName 删除文件的全路径
*/
public static void delete(String objectName){
ossP.deleteObject(fixedBucket, objectName);
}
/**
* 删除数据
* @param bucketName 桶名称
* @param objectName 删除文件的全路径
*/
public static void delete(String bucketName, String objectName){
ossP.deleteObject(bucketName, objectName);
}
/**
* 检查文件是否存在
* @param objectName 文件所在oss中的全路径
* @return 返回是否
*/
public static boolean checkExist(String objectName){
boolean exist = ossP.doesObjectExist(fixedBucket, objectName);
return exist;
}
/**
* 检查文件是否存在
* @param bucketName 桶名称
* @param objectName 文件所在oss中的全路径
* @return 返回是否
*/
public static boolean checkExist(String bucketName, String objectName){
boolean exist = ossP.doesObjectExist(bucketName, objectName);
return exist;
}
//如果需要使用异步调用则在需要的方法上加上@Async注解即可
}
7.控制类
这里只以存取字符串为例展示存取功能
OssController.java
package com.oss.controller;
import com.oss.utils.OssUtil;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
/**
* @ClassDescription: 控制类,操作数据存取的请求接口
* @Author:李白
* @Date:2023/3/7 11:38
*/
@RestController
@EnableAutoConfiguration
@RequestMapping("/oss-test")
public class OssController {
@CrossOrigin
@RequestMapping(value = "/up",method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String ossUpload(){
String bucketName = "bucketName-123";
String upStringContent = "this is a oss test content";
String fileName = "test2.text";
String objectName = "321folder/21oss/"+fileName;
OssUtil.uploadString(bucketName, objectName, upStringContent);
return "oss 上传数据!";
}
@CrossOrigin
@RequestMapping(value = "/down",method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String ossDownload() throws IOException {
String bucketName = "bucketName-123";
String fileName = "test2.text";
String objectName = "321folder/21oss/"+fileName;
String fileContent = OssUtil.downloadString(bucketName, objectName);
return "oss 下载数据 内容:"+fileContent;
}
}
8.postmen请求调用
上传数据:
127.0.0.1:8088/oss-test/up
oss客户端查看:
下载(读取)数据:
127.0.0.1:8088/oss-test/down
postman返回读取内容:
总结:
1
这里只以字符串为例实现了存取,工具类中包含文件、流、字符串等方式进行存取数据,基本都是一样的操作。2
对于oss的使用,配置参数需要考虑到安全问题,所以最好是以读取参数的方式。其次在操作存取数据时,大一些的数据上传下载效率会变低,这时可以考虑用异步调用注解。3
需要注意的点是配置bean的时候参数字段不能用private修饰,虽然不会报错,但读取的时候是读不到私有参数生成的bean中的值的。
拓展:
对于oss相关的名词作一些了解:
1.OSS
-全称为Object Storage Service 对象存储服务,是一种使用HTTP API存储和检索非结构化数据和元数据对象的工具。 即将文件传到云数据库中,云数据库提供文件上传和下载等服务。2.endipoint
oss对外服务的访问域名,这里注意,内外网访问同一云数据库的域名是不同的。3.accessKeyId
访问身份验证的用户标识。4.accessKeySecret
用来身份验证的密钥(用户加密签名字符串、oss验证签名字符串的密钥,此密钥安全保存不要泄露)5.bucket
存储空间,用于存储对象的容器,数据隶属于某个bucket。6.bucketName
即bucket名,存储空间名称,又称为桶名称,是oss下最高一层的存储空间。7.objcet
对象或者文件,是oss存储数据的基本单元,唯一标识为文件名(key)。8.objectName
即objcet名,文件存储的路径(包含了文件名及后缀)。9.region
地域,oss云数据库所在的地理位置,可根据自身情况选择数据存储的地域。