若依Springboot3集成腾讯云COS对象存储私有读写(亲测可用)

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  大家根据自己的端口号来修改

上传:

下载:

下载不知道什么原因  拿到的是乱码 但是方法是没问题的

写的有什么问题欢迎大家补充  谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值