首先进入对象存储的控制台,创建存储桶。
可以把存储桶理解为一个存储空间,和文件系统类似,都是根据路径找到文件或目录(比如 /test/aaa.jpg
)。可以多个项目共用一个存储桶,也可以每个项目一个。
点击创建存储桶,注意地域选择国内(离用户较近的位置)。此处访问权限先选择“公有读私有写”,因为我们的存储桶要存储允许用户公开访问图片。而如果整个存储桶要存储的文件都不允许用户访问,建议选择私有读写,更安全。
默认告警一定要勾选!因为对象存储服务的存储和访问流量都是计费的,超限后我们要第一时间得到通知并进行相应的处理。
其余选默认即可
引入cos依赖
<!-- 腾讯云 cos 服务 -->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.227</version>
</dependency>
在项目的 config
包下新建 CosClientConfig
类。负责读取配置文件,并创建一个 COS 客户端的 Bean。
@Configuration
@ConfigurationProperties(prefix = "cos.client")
@Data
public class CosClientConfig {
/**
* 域名
*/
private String host;
/**
* secretId
*/
private String secretId;
/**
* 密钥(注意不要泄露)
*/
private String secretKey;
/**
* 区域
*/
private String region;
/**
* 桶名
*/
private String bucket;
@Bean
public COSClient cosClient() {
// 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region(region));
// 生成cos客户端
return new COSClient(cred, clientConfig);
}
}
设置配置文件
注意防止密码泄露! 所以我们新建 application-local.yml
文件,如果有git,要在 .gitignore
中忽略该文件的提交,这样就不会将代码等敏感配置提交到代码仓库了。
注意配置激活文件或在主配置文件中指定激活的环境配置:
spring:profiles:active:local
application-local.yml
配置如下:
# 对象存储配置
cos:
client:
host: xxxxxxx
secretId: xxxxxxx
secretKey: xxxxxxx
region: xxxxxxx
bucket: xxxxxxx
host为自己的桶名 可以在 COS 控制台的域名信息部分找到:登录 - 腾讯云
secretId、secretKey 密钥对:在腾讯云访问管理 密钥管理中获取。
region 表示地域名,可以 点此获取。
bucket 是存储桶名,可以点进存储桶详情页获取:登录 - 腾讯云
创建通用类
参考 官方文档 的“上传对象”部分,可以编写出文件上传的代码。
新建CosManager
类,提供通用的对象存储操作,比如文件上传、文件下载等
@Component
public class CosManager {
@Resource
private CosClientConfig cosClientConfig;
@Resource
private COSClient cosClient;
//一些操作 COS 的方法
/**
* 上传对象
*
* @param key 唯一键
* @param file 文件
*/
public PutObjectResult putObject(String key, File file) {
PutObjectRequest putObjectRequest = new PutObjectRequest(cosClientConfig.getBucket(), key,
file);
return cosClient.putObject(putObjectRequest);
}
/**
* 下载对象
*
* @param key 唯一键
*/
public COSObject getObject(String key) {
GetObjectRequest getObjectRequest = new GetObjectRequest(cosClientConfig.getBucket(), key);
return cosClient.getObject(getObjectRequest);
}
}
测试 新建textFileController
流程是先接受用户上传的文件,指定上传的路径,然后调用 cosManager.putObject
方法上传文件到 COS 对象存储;上传成功后,会返回一个文件的 key(其实就是文件路径),便于我们访问和下载文件。
@Slf4j
@RestController
@RequestMapping
//文件上传
public class FileController {
//测试文件上传
@Resource
private CosManager cosManager;
//测试文件上传
@PostMapping("/text/upload")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<String> textUpload(@RequestPart MultipartFile multipartFile) {
//获取文件名
String filename = multipartFile.getOriginalFilename();
//使用 String.format 构造文件存储路径,格式为 /test/文件名
String filepath = String.format("/text/%s", filename);
File file = null;
try {
file = File.createTempFile(filepath, null);
//将上传的文件写入临时文件
multipartFile.transferTo(file);
//上传到 COS(云存储)
cosManager.putObject(filepath, file);
//返回文件名 也就是可访问的地址
return ResultUtils.success(filepath);
} catch (Exception e) {
log.error("文件上传异常,路径为 {}", filepath, e);
e.printStackTrace();
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传失败");
} finally {
if (file != null) {
boolean delete = file.delete();
if (!delete) {
log.error("本地文件删除失败{}", filepath);
}
}
}
}
/**
* 测试文件下载
*
* @param filepath 文件路径
* @param response 响应对象
*/
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
@GetMapping("/test/download/")
public void testDownloadFile(String filepath, HttpServletResponse response) throws IOException {
COSObjectInputStream cosObjectInput = null;
try {
COSObject cosObject = cosManager.getObject(filepath);
cosObjectInput = cosObject.getObjectContent();
// 处理下载到的流
byte[] bytes = IOUtils.toByteArray(cosObjectInput);
// 设置响应头
response.setContentType("application/octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=" + filepath);
// 写入响应
response.getOutputStream().write(bytes);
response.getOutputStream().flush();
} catch (Exception e) {
log.error("file download error, filepath = " + filepath, e);
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "下载失败");
} finally {
if (cosObjectInput != null) {
cosObjectInput.close();
}
}
}
}
打开 Swagger 接口文档,测试文件上传和下载即可:
注 Spring默认文件最大为1M
更改即可
servlet:
multipart:
max-file-size: 10MB