引言:之前本来是用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/ObjectNameStringBuilder 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 {@Resourceprivate 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.pngString 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的MetadataObjectMetadata objectMetadata = new ObjectMetadata();// - 使用输入流存储,需要设置请求长度objectMetadata.setContentLength(inputStream.available());// - 设置缓存objectMetadata.setCacheControl("no-cache");// - 设置Content-TypeobjectMetadata.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、在接口中使用
@Resourceprivate 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);}