zqy
2025-03-25 b844453877db2b534106383497fc55fbdfc6a427
对象存储的上传下载删除接口
5个文件已修改
2个文件已添加
300 ■■■■■ 已修改文件
ruoyi-admin/pom.xml 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/zhang/CosController.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/pom.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhang-content/pom.xml 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhang-content/src/main/java/com/ruoyi/service/impl/GetOrPut.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/pom.xml
@@ -77,6 +77,23 @@
            <artifactId>ruoyi-common</artifactId>
        </dependency>
        <!-- 腾讯云 -->
        <dependency>
            <groupId>com.qcloud</groupId>
            <artifactId>cos_api</artifactId>
            <version>5.6.227</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <build>
ruoyi-admin/src/main/java/com/ruoyi/web/controller/zhang/CosController.java
New file
@@ -0,0 +1,91 @@
package com.ruoyi.web.controller.zhang;
import com.qcloud.cos.utils.IOUtils;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.service.impl.GetOrPut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
@RestController
@RequestMapping("/cos")
public class CosController {
    @Autowired
    private GetOrPut getOrPut;
    // 文件上传
    @PostMapping("/upload")
    public AjaxResult upload(@RequestParam("file") MultipartFile file) {
        String key;
        try {
           key =  getOrPut.uploadFile(file);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        System.out.println("dfsdgd");
        HashMap<String,String> map = new HashMap<>();
        map.put("key",key);
        return AjaxResult.success(map);
    }
    // 文件下载
    @GetMapping("/download")
    public void download(@RequestParam String key, HttpServletResponse response) {
        try (InputStream inputStream = getOrPut.getFileStream(key)) {
            String fileExtension = getFileExtension(key);
            String contentType = getContentType(fileExtension);
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment; filename=\"" + key + "\"");
            IOUtils.copy(inputStream, response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException("文件下载失败", e);
        }
    }
    private String getFileExtension(String key) {
        int dotIndex = key.lastIndexOf('.');
        if (dotIndex == -1) {
            return "";  // 没有扩展名
        }
        return key.substring(dotIndex + 1).toLowerCase();
    }
    private String getContentType(String fileExtension) {
        switch (fileExtension) {
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            case "png":
                return "image/png";
            case "gif":
                return "image/gif";
            case "pdf":
                return "application/pdf";
            case "txt":
                return "text/plain";
            default:
                return "application/octet-stream";  // 默认类型
        }
    }
    @DeleteMapping("/delete")
    public AjaxResult delete(@RequestParam String key){
        try {
            getOrPut.deleteFile(key);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return AjaxResult.success("文件上传成功");
    }
}
ruoyi-admin/src/main/resources/application.yml
@@ -144,3 +144,11 @@
  # 匹配链接
  urlPatterns: /system/*,/monitor/*,/tool/*
#腾讯云
tencent:
  cos:
    secret-id: AKIDOelfP1QbZJq9E5j9LI2YptwlNlvsbBf0       # 替换为实际SecretId
    secret-key: DCxVpvnRt89wVs2ygATYZWOMFzXtAHB3    # 替换为实际SecretKey
    bucket-name: examplebucket-22222-1346631008  # 存储桶名称
    region: ap-guangzhou            # 存储桶地域
    base-url: https://examplebucket-22222-1346631008.cos.ap-guangzhou.myqcloud.com # 访问基础URL
ruoyi-common/pom.xml
@@ -181,6 +181,7 @@
        </dependency>
    </dependencies>
    <build>
ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java
@@ -34,6 +34,15 @@
        {
            requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
        }
        else if (request instanceof HttpServletRequest
                && StringUtils.startsWithIgnoreCase(request.getContentType(), "image/"))
        {
            // 对于图片请求,不做任何包装
            chain.doFilter(request, response);
            return;  // 直接返回,避免后续的代码执行
        }
        if (null == requestWrapper)
        {
            chain.doFilter(request, response);
zhang-content/pom.xml
@@ -73,6 +73,34 @@
            <artifactId>spring-test</artifactId>
        </dependency>
        <!-- 腾讯云 -->
        <dependency>
            <groupId>com.qcloud</groupId>
            <artifactId>cos_api</artifactId>
            <version>5.6.227</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.8</version>
        </dependency>
    </dependencies>
    <build>
zhang-content/src/main/java/com/ruoyi/service/impl/GetOrPut.java
New file
@@ -0,0 +1,146 @@
package com.ruoyi.service.impl;
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.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.TransferManagerConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Service
@ConfigurationProperties(prefix = "tencent.cos")
public class GetOrPut {
    // 从配置文件读取的参数
    private String secretId;
    private String secretKey;
    private String bucketName;
    private String region;
    private String baseUrl;
    private COSClient cosClient;
    private TransferManager transferManager;
    // 初始化配置
    @PostConstruct
    private void init() {
        // 1. 初始化用户身份信息
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        // 2. 设置bucket的区域
        Region region = new Region(this.region);
        ClientConfig clientConfig = new ClientConfig(region);
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 3. 生成cos客户端
        cosClient = new COSClient(cred, clientConfig);
        // 4. 初始化传输管理器(用于大文件上传)
        ExecutorService threadPool = Executors.newFixedThreadPool(32);
        TransferManagerConfiguration transferConfig = new TransferManagerConfiguration();
        transferConfig.setMultipartUploadThreshold(5 * 1024 * 1024);
        transferManager = new TransferManager(cosClient, threadPool);
        transferManager.setConfiguration(transferConfig);
    }
    /**
     * 上传文件(MultipartFile方式)
     * @param file 上传的文件
     * @return 文件访问URL
     */
    public String uploadFile(MultipartFile file) {
        try {
            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String fileExt = originalFilename.substring(originalFilename.lastIndexOf("."));
            String key = java.util.UUID.randomUUID().toString() + fileExt;
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(file.getSize());
            metadata.setContentType(file.getContentType());
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    bucketName,
                    key,
                    file.getInputStream(),
                    metadata
            );
            // 上传文件
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            return baseUrl + "/" + key;
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败", e);
        }
    }
    /**
     * 上传本地文件
     * @param localFilePath 本地文件路径
     * @return 文件访问URL
     */
    public String uploadLocalFile(String localFilePath) {
        File localFile = new File(localFilePath);
        String key = UUID.randomUUID().toString() + getFileExtension(localFile.getName());
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
        cosClient.putObject(putObjectRequest);
        return baseUrl + "/" + key;
    }
    /**
     * 下载文件到本地
     * @param key 文件唯一标识
     * @param localFilePath 本地存储路径
     */
    public void downloadFile(String key, String localFilePath) {
        File downFile = new File(localFilePath);
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key);
        cosClient.getObject(getObjectRequest, downFile);
    }
    /**
     * 获取文件输入流
     * @param key 文件唯一标识
     * @return 文件输入流
     */
    public InputStream getFileStream(String key) {
        COSObject cosObject = cosClient.getObject(bucketName, key);
        return cosObject.getObjectContent();
    }
    /**
     * 删除文件
     * @param key 文件唯一标识
     */
    public void deleteFile(String key) {
        cosClient.deleteObject(bucketName, key);
    }
    // 获取文件扩展名
    private String getFileExtension(String fileName) {
        return fileName.substring(fileName.lastIndexOf("."));
    }
    // Getter/Setter 用于配置注入
    public void setSecretId(String secretId) { this.secretId = secretId; }
    public void setSecretKey(String secretKey) { this.secretKey = secretKey; }
    public void setBucketName(String bucketName) { this.bucketName = bucketName; }
    public void setRegion(String region) { this.region = region; }
    public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; }
}