1.创建存储桶
地域选离自己近的 名称自定义 权限私有读写

然后一直下一步即可


创建之后得到了一个容器 先上传一个文件看看

上传成功

点击右上角 账号-访问管理

左边 访问管理-访问密钥-api密钥管理 新建密钥 为了避免忘记密钥的情况 建议先把他复制到记事本

找到桶列表 配置管理

找到这些值也记到记事本中

注意:区域记后面括号里的即可 也就是比如你是选择的北京 记 ap-beijing 即可
2.后端代码
在admin模块中找到application.yml 在最下面新增存储桶的值
# cos对象存储
cos:
client:
accessKey: 刚复制到记事本的SecretId的值
secretKey: 刚复制到记事本的SecretKey的值
region: 区域
bucket: 桶名
cosHost: 访问域名
# 过期时间单位是毫秒 默认为1小时
expireTime: 3600000
然后把记着的值对应的都填到这里
在common\config中新建方法CosClientConfig

代码复制下面的 初始化cos对象存储:
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.region.Region;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 腾讯云对象存储客户端
*/
@Configuration
@ConfigurationProperties(prefix = "cos.client")
@Data
public class CosClientConfig {
/**
* SecretId
*/
private String accessKey;
/**
* SecretKey
*/
private String secretKey;
/**
* 区域
*/
private String region;
/**
* 桶名
*/
private String bucket;
/**
* 访问域名
*/
private String cosHost;
/**
* 响应头
*/
private String cosHostHeader;
/**
* 过期时间
*/
private String expireTime;
@Bean
public COSClient cosClient() {
// 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(accessKey, secretKey);
// 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region(region));
// 生成cos客户端
return new COSClient(cred, clientConfig);
}
}
在utils中新建cos软件包 新建CosManager模块

代码如下 里面写了几种上传下载方法 都已经测过了可以用 有写注释大家自己研究 也欢迎大家继续补充:
import com.qcloud.cos.COSClient;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.model.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import javax.annotation.Resource;
import com.qcloud.cos.utils.IOUtils;
import com.yltxcn.common.config.CosClientConfig;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* Cos 对象存储操作
*/
@Component
public class CosManager {
@Resource
private CosClientConfig cosClientConfig;
@Resource
private COSClient cosClient;
private static final Logger logger = LoggerFactory.getLogger(CosManager.class);
/**
* 上传对象
* @param key 唯一键
* @param localFilePath 本地文件路径
* @return 上传结果
*/
public PutObjectResult putObject(String key, String localFilePath) {
PutObjectRequest putObjectRequest = new PutObjectRequest(cosClientConfig.getBucket(), key, new File(localFilePath));
return cosClient.putObject(putObjectRequest);
}
/**
* 上传对象
* @param key 唯一键
* @param file 文件
* @return 上传结果
*/
public PutObjectResult putObject(String key, File file) {
PutObjectRequest putObjectRequest = new PutObjectRequest(cosClientConfig.getBucket(), key, file);
return cosClient.putObject(putObjectRequest);
}
/**
* 下载对象(没有过期时间)
* @param key 唯一键
* @return COSObject
*/
public COSObject getObject(String key) {
GetObjectRequest getObjectRequest = new GetObjectRequest(cosClientConfig.getBucket(), key);
return cosClient.getObject(getObjectRequest);
}
/**
* 生成下载链接
* @param key 唯一键
* @param expiration 下载链接过期时间
* @return 生成的下载链接
*/
public String generatePresignedUrl(String key, Date expiration) {
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(cosClientConfig.getBucket(), key, HttpMethodName.GET)
.withMethod(HttpMethodName.GET)
.withExpiration(expiration);
URL url = cosClient.generatePresignedUrl(generatePresignedUrlRequest);
return url.toString();
}
/**
* 上传文件到 COS
* @param multipartFile 上传的文件
* @return 文件路径
*/
public ResponseEntity<String> uploadFile(@RequestPart("file") MultipartFile multipartFile) {
/* 文件目录 */
String filename = multipartFile.getOriginalFilename();
String filepath = String.format("/test/%s", filename);
Path tempFilePath = null;
try {
/* 创建临时文件 */
tempFilePath = Files.createTempFile("temp_", "_" + filename);
multipartFile.transferTo(tempFilePath.toFile());
/* 上传文件 */
putObject(filepath, tempFilePath.toFile());
/* 返回文件路径 */
return ResponseEntity.ok(filepath);
} catch (IOException ioException) {
logger.error("File IO error, filepath = {}", filepath, ioException);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("File upload failed due to IO error.");
} catch (Exception e) {
logger.error("File upload error, filepath = {}", filepath, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("File upload failed.");
} finally {
if (tempFilePath != null) {
try {
/* 删除临时文件 */
Files.delete(tempFilePath);
} catch (IOException e) {
logger.error("File delete error, filepath = {}", filepath, e);
}
}
}
}
/**
* 通过预签名 URL 下载文件(有过期时间)
* @param filepath 文件路径
* @param response HttpServletResponse
* @throws IOException IO 异常
*/
public void downloadFile(String filepath, HttpServletResponse response) throws IOException {
try {
/* 生成私有下载链接 */
Date expiration = new Date(System.currentTimeMillis() + Long.parseLong(cosClientConfig.getExpireTime()));
String presignedUrl = generatePresignedUrl(filepath, expiration);
/* 使用预签名 URL 下载文件 */
URL url = new URL(presignedUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
/* 处理连接响应 */
try (InputStream inputStream = connection.getInputStream()) {
byte[] bytes = IOUtils.toByteArray(inputStream);
/* 设置响应头 */
response.setContentType(cosClientConfig.getCosHostHeader());
String encodedFilename = URLEncoder.encode(filepath, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFilename + "\"");
/* 写入响应输出流 */
response.getOutputStream().write(bytes);
response.getOutputStream().flush();
}
} catch (IOException e) {
logger.error("File download error, filepath = {}", filepath, e);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "File download failed.");
}
}
/**
* 直接从 COS 下载文件(无过期时间)
* @param filepath 文件路径
* @param response HttpServletResponse
* @throws IOException IO 异常
*/
public void downloadFileDirect(String filepath, HttpServletResponse response) throws IOException {
COSObjectInputStream cosObjectInput = null;
try {
/* 获取 COS 对象 */
COSObject cosObject = getObject(filepath);
cosObjectInput = cosObject.getObjectContent();
/* 将 COS 对象内容转换为字节数组 */
byte[] bytes = IOUtils.toByteArray(cosObjectInput);
/* 设置响应头 */
response.setContentType(cosClientConfig.getCosHostHeader());
String encodedFilename = URLEncoder.encode(filepath, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFilename + "\"");
/* 写入响应输出流 */
response.getOutputStream().write(bytes);
response.getOutputStream().flush();
} catch (Exception e) {
logger.error("File download error, filepath = {}", filepath, e);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "File download failed.");
} finally {
/* 确保输入流关闭 */
if (cosObjectInput != null) {
try {
cosObjectInput.close();
} catch (IOException e) {
logger.error("Error closing COSObjectInputStream", e);
}
}
}
}
/**
* 获取文件下载链接 (有过期时间)
* @param filepath 文件路径
* @return 文件的下载链接
*/
public ResponseEntity<String> getFileDownloadLink(String filepath) {
try {
/* 生成私有下载链接(有效期根据配置) */
Date expiration = new Date(System.currentTimeMillis() + Long.parseLong(cosClientConfig.getExpireTime()));
String presignedUrl = generatePresignedUrl(filepath, expiration);
/* 返回下载链接 */
return ResponseEntity.ok(presignedUrl);
} catch (Exception e) {
logger.error("Error generating download link for filepath = {}", filepath, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to generate download link.");
}
}
}
写个表现层调用下方法:
@RestController
@RequestMapping("/file")
public class FileController {
@Autowired
private CosManager cosManager;
/**
* 上传文件
* @param multipartFile 文件
* @return 路径+文件名 /test/测试.txt
*/
@Anonymous
@PostMapping("/upload")
public ResponseEntity<String> uploadFile(@RequestPart("file") MultipartFile multipartFile) {
return cosManager.uploadFile(multipartFile);
}
/**
* 下载文件
*/
@Anonymous
@PostMapping("/download")
public void downloadFile(String filepath, HttpServletResponse response) throws IOException {
cosManager.downloadFile(filepath, response);
}
}
3.测试
用postman来测试下接口 我的后端端口号是1668,默认是8080 大家根据自己的端口号来修改
上传:

下载:

下载不知道什么原因 拿到的是乱码 但是方法是没问题的
写的有什么问题欢迎大家补充 谢谢

被折叠的 条评论
为什么被折叠?



