引言:之前本来是用OSS做存储的,但是上线小程序发现OSS貌似消费比COS多一些,所以之前做了技术搬迁,最近想起,打算做个笔记记录一下,这里省去在阿里云注册OSS或腾讯云中注册COS应用了。
一、OSS
1、配置yml
qupai:
alioss:
endpoint: ${qupai.alioss.endpoint}
access-key-id: ${qupai.alioss.access-key-id}
access-key-secret: ${qupai.alioss.access-key-secret}
bucket-name: ${qupai.alioss.bucket-name}
2、编写配置类读取yml配置
@Component
@ConfigurationProperties(prefix = "qupai.alioss")
@Data
public class AliOssProperties {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
}
3、编写COS工具类
@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
/**
* 文件上传
*
* @param bytes
* @param objectName
* @return
*/
public String upload(byte[] bytes, String objectName) {
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 创建PutObject请求。
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
} 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();
}
}
//文件访问路径规则 https://BucketName.Endpoint/ObjectName
StringBuilder stringBuilder = new StringBuilder("https://");
stringBuilder
.append(bucketName)
.append(".")
.append(endpoint)
.append("/")
.append(objectName);
log.info("文件上传到:{}", stringBuilder.toString());
return stringBuilder.toString();
}
}
4、声明配置类在程序开始时交给bean对象注入
/**
* 配置类,用于创建AliOssUtils对象
*/
@Configuration//声明配置类
@Slf4j
public class OssConfiguration {
@Bean//程序开始时交给bean对象注入
@ConditionalOnMissingBean//保证spring容器里面只有一个utils对象(当没有这个bean对象再去创建,有就没必要去创建了)
public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
log.info("开始创建阿里云文件上传工具类对象: {}",aliOssProperties);
return new AliOssUtil(aliOssProperties.getEndpoint(),
aliOssProperties.getAccessKeyId(),
aliOssProperties.getAccessKeySecret(),
aliOssProperties.getBucketName());
}
}
5、在接口中使用
/**
* 通用接口
*/
@RestController("adminCommonController")
@RequestMapping("/admin/common")
@Tag(name = "通用接口")
@Slf4j
public class CommonController {
@Resource
private AliOssUtil aliOssUtil;
/**
* 文件上传
* @param file
* @return
*/
@PostMapping("/upload")
@Operation(summary="文件上传")
public Result<String> upload(MultipartFile file) {
log.info("上传文件:{}", file);
//file.getBytes(),file对象转成的一个数组,objectName文件名通过uuid来生成
try {
//原始文件名
String originalFilename = file.getOriginalFilename();
//截取元素文件名的后缀,dfdfdf.png
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
//构造新的文件名称
String objectName=UUID.randomUUID().toString()+extension;
//文件的请求路径
String filePath = aliOssUtil.upload(file.getBytes(), objectName);
return Result.success(filePath);
} catch (IOException e) {
log.error("文件上传失败: {}", e);
}
return Result.error(MessageConstant.UPLOAD_FAILED);
}
}
二、COS
1、配置yml
quick:
tencentcos:
appid: ${quick.tencentcos.appid}
secret-id: ${quick.tencentcos.secret-id}
secret-key: ${quick.tencentcos.secret-key}
bucket-name: ${quick.tencentcos.bucket-name}
cos-path: ${quick.tencentcos.cos-path}
region: ${quick.tencentcos.region}
2、编写配置类读取yml配置
/*
* @读取yml配置
*/
@Component
@Data
@ConfigurationProperties(prefix = "quick.tencentcos")
public class TencentCosProperties {
private String appid;
private String secretId;
private String secretKey;
private String bucketName;
private String cosPath;
private String region;
}
3、编写COS工具类
@Data
@AllArgsConstructor
@Slf4j
public class TencentCosUtil {
// 腾讯云cos 配置信息
private String appid;
private String secretId;
private String secretKey;
private String bucketName;
private String cosPath;
private String region;
/**
* 1.调用静态方法getCosClient()就会获得COSClient实例
* 2.本方法根据永久密钥初始化 COSClient的,官方是不推荐,官方推荐使用临时密钥,是可以限制密钥使用权限,创建cred时有些区别
*
* @return COSClient实例
*/
public COSClient getCosClient() {
// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2.1 设置存储桶的地域(上文获得)
Region region_new = new Region(region);
ClientConfig clientConfig = new ClientConfig(region_new);
// 2.2 使用https协议传输
clientConfig.setHttpProtocol(HttpProtocol.https);
// 3 生成 cos 客户端
// 返回COS客户端
return new COSClient(cred, clientConfig);
}
/**
* 上传文件
*
* @param file 上传的文件
* @return 返回文件的url
*/
public String upLoadFile(MultipartFile file) {
try {
// 获取上传的文件的输入流
InputStream inputStream = file.getInputStream();
// 避免文件覆盖,获取文件的原始名称,如123.jpg,然后通过截取获得文件的后缀,也就是文件的类型
String originalFilename = file.getOriginalFilename();
// 获取文件的类型
String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
// 使用UUID工具 创建唯一名称,放置文件重名被覆盖,在拼接上上命令获取的文件类型
String fileName = UUID.randomUUID().toString() + fileType;
// 指定文件上传到 COS 上的路径,即对象键最终文件会传到存储桶名字中的images文件夹下的fileName名字
String key = "/images/" + fileName;
// 创建上传Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
// - 使用输入流存储,需要设置请求长度
objectMetadata.setContentLength(inputStream.available());
// - 设置缓存
objectMetadata.setCacheControl("no-cache");
// - 设置Content-Type
objectMetadata.setContentType(fileType);
// 上传文件
PutObjectResult putResult = getCosClient().putObject(bucketName, key, inputStream, objectMetadata);
// 创建文件的网络访问路径
String url = cosPath + key;
// 关闭 cosClient,并释放 HTTP 连接的后台管理线程
getCosClient().shutdown();
return url;
} catch (Exception e) {
e.printStackTrace();
// 发生IO异常、COS连接异常等,返回空
return null;
}
}
}
4、声明配置类在程序开始时交给bean对象注入
/**
* 配置类,用于创建AliOssUtils对象
*/
@Configuration//声明配置类
@Slf4j
public class CosConfiguration {
@Bean//程序开始时交给bean对象注入
@ConditionalOnMissingBean//保证spring容器里面只有一个utils对象(当没有这个bean对象再去创建,有就没必要去创建了)
public TencentCosUtil tencentCosUtil(TencentCosProperties tencentCosProperties){
log.info("开始创建腾讯云文件上传工具类对象: {}",tencentCosProperties);
return new TencentCosUtil(tencentCosProperties.getAppid(),
tencentCosProperties.getSecretId(),
tencentCosProperties.getSecretKey(),
tencentCosProperties.getBucketName(),
tencentCosProperties.getCosPath(),
tencentCosProperties.getRegion());
}
}
5、在接口中使用
@Resource
private TencentCosUtil tencentCosUtil;
/**
* 文件上传
*/
@PostMapping("/upload")
//@ApiOperation("文件上传")
@Operation(summary = "文件上传")
public Result<String> upload(MultipartFile file) {
log.info("上传文件:{}", file);
log.info("正在上传,文件名{}",file.getOriginalFilename());
String url = tencentCosUtil.upLoadFile(file);
log.info("文件的Url:{}",url);
return Result.success(url);
}