乐趣区

关于后端:文件上传还存储在应用服务器

个别我的项目开发中都会有文件、图片、视频等文件上传并可能拜访的场景。要实现这样的场景,要么把文件存储在应用服务器上,要么搭建文件服务来存储。然而这两种形式也有不少的毛病,减少运维的老本。
因而,谋求用户体验的我的项目可能会思考应用第三方的云服务来实现存储,目前市场上支流的厂商有:七牛云、阿里云 OSS、腾讯云 COS 等,具体采纳哪种存储计划还需联合我的项目的规模、老本等因素,综合考量。
因为我的是腾讯云的服务器,所以就间接开明了腾讯云的 COS 对象存储。这篇文章就来记录一下,SpringBoot 整合腾讯云 COS 对象存储实现文件上传的。

一、筹备工作
整合前须要做一些筹备工作,开明 COS 对象存储,创立存储通,创立拜访密钥。

  1. 开明腾讯云对象存储服务
    新用户专享,1 米能够购买 1 年的存储。用来学习还是很香的。console.cloud.tencent.com/cos
  1. 创立存储桶
    留神存储桶拜访的拜访权限,设置成私有读公有写。
  1. 密钥治理,创立密钥
    点击新建密钥,会主动生成。

三、整合步骤

  1. 增加 maven 依赖
    代码如下(示例):
    <!– 腾讯云 COS 对象存储 –>
    <dependency>
    <groupId>com.qcloud</groupId>
    <artifactId>cos_api</artifactId>
    <version>5.6.89</version>
    </dependency>
    复制代码
  2. yml 文件减少配置
    代码如下(示例):

    腾讯云 cos 配置

    cos:
    baseUrl: https://xiliu-24.cos.ap-guangzhou.myqcloud.com
    secretId: AKI**ior
    secretKey: zZ*z6
    regionName: ap-guangzhou
    bucketName: xiliu-24
    folderPrefix: /upload
    复制代码

  3. 新建 COS 配置类
    代码如下(示例):
    package com.java.xiliu.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**

  • @author xiliu
  • @description 腾讯云 cos 对象存储配置类
  • @date 2022/10/28
    */

@Data
@Component
@ConfigurationProperties(prefix = “cos”)
public class CosConfig {

/**
 * 存储桶拜访门路
 **/
private String baseUrl;
/**
 * 腾讯云账号秘钥
 **/
private String secretId;
/**
 * 明码秘钥
 **/
private String secretKey;
/**
 * 存储桶地区
 **/
private String regionName;
/**
 * 存储桶名称
 **/
private String bucketName;
/**
 * 上传的根目录
 **/
private String folderPrefix;

public COSClient getCosClient() {
    // 初始化用户信息
    COSCredentials cosCredentials = new BasicCOSCredentials(this.secretId,this.secretKey);
    // 设置地区
    Region region = new Region(this.regionName);
    ClientConfig config = new ClientConfig(region);
    // 生成 COS 客户端
    COSClient client = new COSClient(cosCredentials,config);
    return client;
}

}

复制代码

  1. 新建 COS 上传工具类
    代码如下(示例):
    package com.java.xiliu.common.untils.file;

import com.java.xiliu.common.untils.SpringUtils;
import com.java.xiliu.config.CosConfig;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.UploadResult;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.Upload;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**

  • @author xiliu
  • @description 腾讯云 COS 文件上传工具类
  • @date 2022/10/31
    */

@Slf4j
public class CosClientUtils {

/**
 * 获取配置信息
 */
private static CosConfig cosConfig = SpringUtils.getBean(CosConfig.class);

public static String upload(MultipartFile file, String dir) throws Exception {String originalFilename = file.getOriginalFilename();
    // 文件名
    String name = FilenameUtils.getBaseName(originalFilename) + "_" + System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));
    // 目录
    String folderName = cosConfig.getFolderPrefix() + "/" + dir + "/";
    String key = folderName + name;
    File localFile = null;
    try {localFile = transferToFile(file);
        String filePath = uploadFileToCos(localFile, key);
        log.info("upload COS successful: {}", filePath);
        return filePath;
    } catch (Exception e) {throw new Exception("文件上传失败");
    } finally {localFile.delete();
    }
}

/**
 * 用缓冲区来创立临时文件
 * 应用 MultipartFile.transferTo()
 * @param multipartFile
 * @return
 */
private static File transferToFile(MultipartFile multipartFile) throws IOException {String originalFilename = multipartFile.getOriginalFilename();
    String prefix = originalFilename.split("\\.")[0];
    String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
    File file = File.createTempFile(prefix, suffix);
    multipartFile.transferTo(file);
    return file;
}

/**
 * 上传文件到 COS
 * @param localFile
 * @param key
 * @return
 */
private static String uploadFileToCos(File localFile, String key) throws InterruptedException {PutObjectRequest putObjectRequest = new PutObjectRequest(cosConfig.getBucketName(), key, localFile);
    // 获取连贯
    COSClient cosClient = cosConfig.getCosClient();
    // 创立线程池
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(8, 16,
            4, TimeUnit.SECONDS, new ArrayBlockingQueue(10), new ThreadPoolExecutor.AbortPolicy());
    // 传入一个 threadPool, 若不传入线程池, 默认 TransferManager 中会生成一个单线程的线程池
    TransferManager transferManager = new TransferManager(cosClient, threadPool);
    // 返回一个异步后果 Upload, 可同步的调用 waitForUploadResult 期待 upload 完结, 胜利返回 UploadResult, 失败抛出异样
    Upload upload = transferManager.upload(putObjectRequest);
    UploadResult uploadResult = upload.waitForUploadResult();
    transferManager.shutdownNow();
    cosClient.shutdown();
    String filePath = cosConfig.getBaseUrl() + uploadResult.getKey();
    return filePath;
}

}

复制代码

  1. 新建 Controller 上传接口
    代码如下(示例):
    @ApiOperation(value = “ 用户头像上传 ”)
    @PostMapping(“/profile/avatar”)
    public R uploadAvatar(@RequestParam(“avatarfile”) MultipartFile file) throws Exception {

    if (!file.isEmpty()) {String avatar = CosClientUtils.upload(file, "avatar");
        return R.ok(avatar);
    }
    return R.error("上传头像异样,请分割管理员");

    }
    复制代码

  2. 测试
    应用 Swagger 接口文档或者 Postman 测试上传接口,胜利返回地址。应用浏览器关上该返回地址,能够失常预览。

总结
以上就是本文的全部内容了,感激大家的浏览。
如果感觉文章对你有帮忙,还不忘帮忙点赞、珍藏、关注、评论哟,您的反对就是我创作最大的能源!

退出移动版