阿里云OSS对象存储
什么是对象存储OSS
OSS的全称是:Object Storage Service;即对象存储服务。
在数据存储领域,存储数据的主要方法有三种: 文件、块和对象。
简单来说,对象的功能是模块化的单元,每个对象都充当自包含的存储库,其中包含描述权限、隐私、证券、意外事件和其他信息等详细信息的元数据。例如,它类似于一张照片,其中可能包含描述用于拍摄照片的相机设置以及拍摄时间和地点的元数据。
开通阿里云OSS对象存储
搜索OSS对象存储
首先登录,点击立即开通,开通是不需要支付任何费用的
开通后点击控制台,搜索OSS对象存储的控制台
创建Bucket 列表
点击Bucket 列表,点击创建
按照我上面内容创建,可以选择我们想要的配置也可以。
点击确定创建成功
代码实现
首先我是基于springboot项目去实现的
导入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</version>
</dependency>
以下是我编写的工具类
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.model.ObjectMetadata;
import com.kk.auth.util.SpringContextUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 阿里云OSS工具类
*
*/
public class OssUtil {
/**
* 访问域名
*/
private final static String ossAccessDomainUrl;
/**
* bucket 名称
*/
private final static String ossBucketName;
/**
* 封装了 accessKeyId 和 accessKeySecret 的客户端对象
*/
private final static OSSClient client;
static {
// 面试题: 如何实现在一个非Spring容器管理的对象中, 从Spring容器中拿到其他Bean对象.
// Environment 对象的作用就是管理 Spring 容器运行时的各种配置内容
Environment environment = SpringContextUtil.getBean(Environment.class);
String endpointUrl = environment.getProperty("aliyun.oss.endpoint");
ossBucketName = environment.getProperty("aliyun.oss.bucket-name");
ossAccessDomainUrl = environment.getProperty("aliyun.oss.domain");
String keyId = environment.getProperty("aliyun.accessKey.id");
String keySecret = environment.getProperty("aliyun.accessKey.secret");
client = new OSSClient(endpointUrl, CredentialsProviderFactory.newDefaultCredentialProvider(keyId, keySecret),
new ClientConfiguration());
}
/**
* @param fileName 用户文件名称
* @return 实际的cos上文件名称
*/
private static String getRealFileName(String saveFolder, String fileName) {
return StringUtils.isNotEmpty(saveFolder) ? saveFolder + "/" + fileName : fileName;
}
public static String upload(String saveFolder, String contentType, String fileName, InputStream input) {
if (StringUtils.isEmpty(fileName) || StringUtils.isEmpty(contentType) || null == input) {
return null;
}
ObjectMetadata objectMeta = new ObjectMetadata();
objectMeta.setContentType(contentType);
String filePath = getRealFileName(saveFolder, fileName);
try {
client.putObject(ossBucketName, filePath, input, objectMeta);
return ossAccessDomainUrl + filePath;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static String upload(String saveFolder, String contentType, String fileName, long contentLength, InputStream input) {
if (StringUtils.isEmpty(fileName) || StringUtils.isEmpty(contentType) || contentLength <= 0 || null == input) {
return null;
}
ObjectMetadata objectMeta = new ObjectMetadata();
objectMeta.setContentLength(contentLength);
objectMeta.setContentType(contentType);
String filePath = getRealFileName(saveFolder, fileName);
try {
client.putObject(ossBucketName, filePath, input, objectMeta);
return ossAccessDomainUrl + "/" + filePath;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static String upload(String saveFolder, String fileMainName, MultipartFile multipartFile) {
if (null != multipartFile && !multipartFile.isEmpty()) {
try {
String filename = multipartFile.getOriginalFilename();
String extFileName;
if (StringUtils.isNotEmpty(filename)) {
extFileName = filename.substring(filename.lastIndexOf("."));
} else {
extFileName = ".jpg";
}
return upload(saveFolder, multipartFile.getContentType(), fileMainName + extFileName, multipartFile.getSize(), multipartFile.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public static String upload4SpecialName(String saveFolder, String fileName, MultipartFile multipartFile) {
if (null != multipartFile && !multipartFile.isEmpty()) {
try {
return upload(saveFolder, multipartFile.getContentType(), fileName, multipartFile.getSize(), multipartFile.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public static String uploadImgByBase64(String saveFolder, String fileName, String base64ImgContent) {
if (StringUtils.isEmpty(fileName) || StringUtils.isEmpty(base64ImgContent)) {
return null;
}
try {
Matcher matcher = Pattern.compile("^data.(.*?);base64,").matcher(base64ImgContent);
if (matcher.find()) {
base64ImgContent = base64ImgContent.replace(matcher.group(), "");
}
byte[] bytes = Base64Utils.decodeFromString(base64ImgContent);
return upload(saveFolder, "image/jpg", fileName, bytes.length, new ByteArrayInputStream(bytes));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void delete(String fileUrl) {
if (StringUtils.isEmpty(fileUrl)) {
return;
}
try {
fileUrl = fileUrl.replaceFirst(ossAccessDomainUrl, "");
client.deleteObject(ossBucketName, fileUrl);
} catch (OSSException | ClientException e) {
e.printStackTrace();
}
}
public static String getByFileName(String pathFile) {
return ossAccessDomainUrl + client.getObject(ossBucketName, pathFile).getKey();
}
}
实现上诉工具类,需要使用到一个Spring工具类
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Spring工具类,获取Spring上下文对象等
*
*/
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
/**
* 1. SpringContextUtil 被 JVM 加载时, applicationContext 作为静态属性, 就被初始化了, 但是此时是 null 值
* 2. 当 Spring 容器初始化以后, 会管理 SpringContextUtil Bean 对象
* 3. 当 Spring 创建 SpringContextUtil 实例对象时,
* 在初始化阶段会自动调用实现了 ApplicationContextAware 的 setApplicationContext 方法,
* 此时该类中原本静态容器属性就从 null 变成了容器对象
* 4. 当容器启动成功后, 其他业务代码通过该类的静态成员, 就可以直接的访问容器对象, 从容器对象中获取其他 Bean 对象
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringContextUtil.applicationContext == null) {
SpringContextUtil.applicationContext = applicationContext;
}
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
需要把该类配置成一个Bean
@Bean
public SpringContextUtil springContextUtil() {
return new SpringContextUtil();
}
我们回到之前的阿里云OSS工具类,有几个写入yml配置的值
- aliyun.oss.endpoint
- aliyun.oss.bucket-name
- aliyun.oss.domain
- aliyun.accessKey.id
- aliyun.accessKey.secret
aliyun:
accessKey:
id: 授权ID
secret: 授权秘钥
oss:
endpoint: 你的地域节点
bucket-name: 你的bucket名称
domain: 你的Bucket域名
调用OSSUtil内的方法即可实现对象存储,工具类的方法看注释使用即可
如下:
String url = OssUtil.upload("images", fileName, upload);