Bootstrap

JAVA整合腾讯COS(拿来即用)

JAVA整合腾讯COS实现文件上传

1、开通腾讯云对象存储服务
https://console.cloud.tencent.com/cos5
2、创建存储桶
在这里插入图片描述

3、密钥管理,新建密钥
在这里插入图片描述
4:在项目yml文件或者枚举类配置
tengxun:
cos:
SecretId: XXX
SecretKey: XXX
region: ap-shanghai
bucketName: XXX
url: XXX
path: XXX/XXX/ # 上传文件夹路径前缀
policy_expire: 300 # 签名有效期(S)
code_format: utf-8

   SecretId 是你生成的密钥ID,Key是密码,region是地区,url是访问域名,bucketName是桶名

以下是JAVA代码,拿来即用,web端访问controller即可

5:MAVEN添加配置

  <!--COS-->
        <dependency>
            <groupId>com.qcloud</groupId>
            <artifactId>cos_api</artifactId>
            <version>5.6.54</version>
            <scope>compile</scope>
        </dependency>

1: TCCOSConfig类

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 com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.TransferManagerConfiguration;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author L_DY
 * @date 2022/5/6 15:00
 */

@Configuration
@Data
public class TCCOSConfig {

    @Value("${tengxun.cos.SecretId}")
    private String secretId;
    @Value("${tengxun.cos.SecretKey}")
    private String secretKey;

    @Value("${tengxun.cos.region}")
    private String region;

    @Value("${tengxun.cos.bucketName}")
    private String bucketName;

    @Value("${tengxun.cos.url}")
    private String url;

    @Value("${tengxun.cos.path}")
    private String path;

    @Value("${tengxun.cos.policy_expire}")
    public Integer policyExpire;

    @Value("${tengxun.cos.code_format}")
    public String codeFormat;





    @Bean
    // 创建 COSClient 实例
    public COSClient cosClient(){
        // 1 初始化用户身份信息(secretId, secretKey)。
        COSCredentials cred = new BasicCOSCredentials(this.secretId, this.secretKey);
        // 2 设置 bucket 的区域, COS 地域的简称请参照
        Region region = new Region(this.region);
        ClientConfig clientConfig = new ClientConfig(region);
        // 3 生成 cos 客户端。
        COSClient cosClient = new COSClient(cred, clientConfig);
        return cosClient;
    }

    // 创建 TransferManager 实例,这个实例用来后续调用高级接口
    public TransferManager createTransferManager() {
        // 创建一个 COSClient 实例,这是访问 COS 服务的基础实例。
        COSClient cosClient = cosClient();

        // 自定义线程池大小,建议在客户端与 COS 网络充足(例如使用腾讯云的 CVM,同地域上传 COS)的情况下,设置成16或32即可,可较充分的利用网络资源
        // 对于使用公网传输且网络带宽质量不高的情况,建议减小该值,避免因网速过慢,造成请求超时。
        ExecutorService threadPool = Executors.newFixedThreadPool(32);

        // 传入一个 threadpool, 若不传入线程池,默认 TransferManager 中会生成一个单线程的线程池。
        TransferManager transferManager = new TransferManager(cosClient, threadPool);

        // 设置高级接口的配置项
        // 分块上传阈值和分块大小分别为 5MB 和 1MB
        TransferManagerConfiguration transferManagerConfiguration = new TransferManagerConfiguration();
        transferManagerConfiguration.setMultipartUploadThreshold(5*1024*1024);
        transferManagerConfiguration.setMinimumUploadPartSize(1*1024*1024);
        transferManager.setConfiguration(transferManagerConfiguration);

        return transferManager;
    }

    public void shutdownTransferManager(TransferManager transferManager) {
        transferManager.shutdownNow(false);
    }
}

2:PicUploadResult返回结果集

/**  返回结果集
 * @author L_DY
 * @date 2022/5/7 14:25
 */
@Data
public class PicUploadResult {
    // 文件惟一标识
    private String uid;

    // 文件名
    private String name;

    // 状态有:uploading done error removed
    private String status;

    // 服务端响应内容,如:'{"status": "success"}'
    private String response;
}

3:ICosFileService

public interface ICosFileService {

    String uploadFile( MultipartFile file);

    String uploadFile(String fileName, InputStream inputStream);

    /**
     * 根据url上传
     * @param url
     * @return
     */
    String uploadFileByUrl(String url);

    /**
     * 把html里的图片转存
     * @param content
     * @return
     */
    String uploadImgFromHtml(String content);

    OssRecoverVO policy();

    String uploadFileWithFolder(String folder, MultipartFile uploadFile) throws IOException;

}

4:CosFileServiceImpl

/**
 * @author L_DY
 * @date 2022/5/6 15:09
 */
@Service
public class CosFileServiceImpl implements ICosFileService{

    @Autowired
    private COSClient cosClient;

    @Autowired
    private TCCOSConfig tccosConfig;

    //    视频后缀 校验视频格式
    public static final String VIDEO_SUFFIX = "wmv,avi,dat,asf,mpeg,mpg,rm,rmvb,ram,flv,mp4,3gp,mov,divx,dv,vob,mkv,qt,cpk,fli,flc,f4v,m4v,mod,m2t,swf,webm,mts,m2ts";
    //    图片格式
    public static final String IMG_SUFFIX = "jpg,png,jpeg,gif,svg";
    //    音频格式
    public static final String AUDIO_SUFFIX = "cda,wav,mp1,mp2,mp3,wma,vqf";


    @Override
    public String uploadFile(MultipartFile file) {
        String url ="";
        try {
            url = uploadFile(Objects.requireNonNull(file.getOriginalFilename()),file.getInputStream());
        }catch (IOException e) {
            throw new CustomException("图片上传失败");
        }
        return url;
    }

    @Override
    public String uploadFile(String fileName, InputStream inputStream) {
        String url = "";
        assert fileName != null;
        int split = fileName.lastIndexOf(".");
        // 文件后缀,用于判断上传的文件是否是合法的
        String suffix = fileName.substring(split+1);
        fileName = tccosConfig.getPath()+UuidShortUtil.creatShortUUID().toLowerCase() + "." + suffix;
        if(IMG_SUFFIX.contains(suffix) || VIDEO_SUFFIX.contains(suffix) || AUDIO_SUFFIX.contains(suffix)) {
            // 1 初始化用户身份信息(secretId, secretKey)。
            COSCredentials cred = new BasicCOSCredentials(tccosConfig.getSecretId(), tccosConfig.getSecretKey());
            // 2 设置 bucket 的区域, COS 地域的简称请参照
            Region region = new Region(this.tccosConfig.getRegion());
            ClientConfig clientConfig = new ClientConfig(region);
            // 3 生成 cos 客户端。
            COSClient cosClient = new COSClient(cred, clientConfig);
            // 自定义线程池大小,建议在客户端与 COS 网络充足(例如使用腾讯云的 CVM,同地域上传 COS)的情况下,设置成16或32即可,可较充分的利用网络资源
            // 对于使用公网传输且网络带宽质量不高的情况,建议减小该值,避免因网速过慢,造成请求超时。
            ExecutorService threadPool = Executors.newFixedThreadPool(32);

            // 传入一个 threadpool, 若不传入线程池,默认 TransferManager 中会生成一个单线程的线程池。
            TransferManager transferManager = new TransferManager(cosClient, threadPool);

            // 设置高级接口的配置项
            // 分块上传阈值和分块大小分别为 5MB 和 1MB
            TransferManagerConfiguration transferManagerConfiguration = new TransferManagerConfiguration();
            transferManagerConfiguration.setMultipartUploadThreshold(5*1024*1024);
            transferManagerConfiguration.setMinimumUploadPartSize(1*1024*1024);
            transferManager.setConfiguration(transferManagerConfiguration);


            String bucketName = tccosConfig.getBucketName();//储存桶名称
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, inputStream, new ObjectMetadata());

            try {
                Upload upload = transferManager.upload(putObjectRequest);//上传
                UploadResult uploadResult = upload.waitForUploadResult();
                uploadResult.getKey();//上传后的文件名字
            } catch (CosServiceException e) {
                e.printStackTrace();
                throw new CustomException("上传连接获取失败");
            } catch (CosClientException e) {
                e.printStackTrace();
                throw new CustomException("上传连接获取失败");
            } catch (InterruptedException e) {
                e.printStackTrace();
                throw new CustomException("上传连接获取失败");
            }finally {
                transferManager.shutdownNow(true);
            }

           url = tccosConfig.getUrl()+fileName;
        }else {
            //错误的类型,返回错误提示
            throw new CustomException("请选择正确的文件格式");
        }

        return url;
    }

    @Override
    public String uploadFileByUrl(String url) {
        byte[] bytes;
        try {
            bytes = FileUtils.downloadPicture(url);
        }catch (Exception e){
            throw new CustomException("图片下载错误");
        }

        return uploadFile(UUID.randomUUID().toString()+".jpg",new ByteArrayInputStream(bytes));
    }

    @Override
    public String uploadImgFromHtml(String content) {
        //判断content里是否有url
        List<String> imgStrList = StringUtils.getImgStr(content);
        if(CollectionUtils.isEmpty(imgStrList)){
            return content;
        }

        for (String imgUrl : imgStrList) {
            if(imgUrl.startsWith(tccosConfig.getUrl())){
                continue;
            }
            content = content.replace(imgUrl,uploadFileByUrl(imgUrl));
        }

        return content;
    }

    @Override
    public OssRecoverVO policy() {
        OssRecoverVO recoverVO = new OssRecoverVO();
        // 设置用户身份信息。
        // SECRETID 和 SECRETKEY
        String secretId = tccosConfig.getSecretId();
        String secretKey =tccosConfig.getSecretKey();
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);

        // 存储桶
        String bucketName = tccosConfig.getBucketName();
        // 对象键(Key)是对象在存储桶中的唯一标识
        String key = "exampleobject";

        ClientConfig clientConfig = new ClientConfig(new Region(tccosConfig.getRegion()));

        // 用来生成签名
        COSSigner signer = new COSSigner();
        // 设置签名过期时间(可选),若未进行设置,则默认使用 ClientConfig 中的签名过期时间(1小时)
        long expireEndTime = System.currentTimeMillis() + tccosConfig.getPolicyExpire() * 1000;
        Date expiration = new Date(expireEndTime);




        // 填写本次请求的参数
        Map<String, String> params = new HashMap<String, String>();
        params.put("param1", "value1");

        // 填写本次请求的头部
        Map<String, String> headers = new HashMap<String, String>();
        // host 必填
        headers.put(Headers.HOST, clientConfig.getEndpointBuilder().buildGeneralApiEndpoint(bucketName));
        headers.put("header1", "value1");

        // 请求的 HTTP 方法,上传请求用 PUT,下载请求用 GET,删除请求用 DELETE
        HttpMethodName method = HttpMethodName.GET;
        String sign = signer.buildAuthorizationStr(method, key, headers, params, cred, expiration);
        String dir = tccosConfig.getPath() + expiration.getTime() + "_" + UUID.randomUUID().toString().substring(0, 8);


        // OSS accesskeyId
        recoverVO.setAccessid(secretId);
        // 协议
      /*  recoverVO.setPolicy();*/
        // 签名
        recoverVO.setSignature(sign);
        // 目录名字
        recoverVO.setDir(dir);
        // 提交地址
        recoverVO.setHost(tccosConfig.getUrl());
        // 到期时间
        recoverVO.setExpire(String.valueOf(expireEndTime / 1000));

        return recoverVO;
    }

    @Override
    public String uploadFileWithFolder(String folder, MultipartFile uploadFile) throws IOException {
        if (Objects.isNull(uploadFile)){
            throw new CustomException(BusinessExceptionCodeEnums.PARAMS_ERROR);
        }
        String fileExtension = FileNameUtil.extName(uploadFile.getOriginalFilename());
        // 校验上传的格式
        boolean isLegal = false;
        // 封装Result对象,而且将文件的byte数组放置到result对象中
        if(IMG_SUFFIX.contains(fileExtension.toLowerCase()) || VIDEO_SUFFIX.contains(fileExtension.toLowerCase()) || AUDIO_SUFFIX.contains(fileExtension.toLowerCase())) {
            // 1 初始化用户身份信息(secretId, secretKey)。
            COSCredentials cred = new BasicCOSCredentials(tccosConfig.getSecretId(), tccosConfig.getSecretKey());
            // 2 设置 bucket 的区域, COS 地域的简称请参照
            Region region = new Region(tccosConfig.getRegion());
            ClientConfig clientConfig = new ClientConfig(region);
            // 3 生成 cos 客户端。
            COSClient cosClient = new COSClient(cred, clientConfig);
            // 文件新路径
            String fileName = uploadFile.getOriginalFilename();
            String filePath = tccosConfig.getPath()+folder+"/"+getFilePath(fileName);
            //上传文件
            try {
                // 指定要上传到的存储桶
                String bucketName = tccosConfig.getBucketName();
                // 指定要上传到 COS 上对象键
                String key = filePath;
                //这里的key是查找文件的依据,妥善保管
                cosClient.putObject(bucketName,key,new ByteArrayInputStream(uploadFile.getBytes()),null);
                //设置输出信息
                return tccosConfig.getUrl()+filePath;
            }
            catch (Exception e){
                e.printStackTrace();
                throw new CustomException("上传连接获取失败");
            }finally {
                // 关闭客户端(关闭后台线程)
                cosClient.shutdown();
            }
        }else {
            throw new CustomException("请选择正确的文件格式");
        }
    }


    /**
     * 生成文件路径
     * @param sourceFileName
     * @return
     */
    private String getFilePath(String sourceFileName) {
        DateTime dateTime = new DateTime();
        return  System.currentTimeMillis() + RandomUtils.nextInt(100, 9999) + "." + StringUtils.substringAfterLast(sourceFileName, ".");
    }
}

5:CosFileController

/**
 * @author L_DY
 * @date 2022/5/6 15:32
 */
@RestController
@RequestMapping("/ossUpload")
public class CosFileController {
    @Autowired
    private ICosFileService cosFileService;


    @AnonymousAccess
    @PostMapping("/upload")
    @ResponseBody
    public AjaxResult uploadFile(MultipartFile file){
        return AjaxResult.success(cosFileService.uploadFile(file));
    }


    @AnonymousAccess
    @PostMapping("/uploadVideo")
    public AjaxResult uploadVideo( MultipartFile file) {
        AjaxResult ajax = AjaxResult.success();
        ajax.put("fileName", file.getOriginalFilename());
        ajax.put("url", cosFileService.uploadFile(file));
        return ajax;
    }


    @AnonymousAccess
    @PostMapping("/uploadFileByUrl")
    @ResponseBody
    public AjaxResult uploadFileByUrl(@RequestBody OssReq req){
        String url = cosFileService.uploadFileByUrl(req.getUrl());
        return AjaxResult.success(url);
    }

    @AnonymousAccess
    @PostMapping("/editor/upload")
    @ResponseBody
    public Object uploadFileWithFolder(@RequestParam("upload") MultipartFile file,@RequestParam(value = "folder",required = false,defaultValue = "editorUpload") String folder) throws IOException {
        String url = cosFileService.uploadFileWithFolder(folder, file);
        Map<String,Object> result = new HashMap<>();
        if (StringUtils.isNotEmpty(url)){
            result.put("uploaded",true);
            result.put("url",url);
        }else {
            result.put("uploaded",false);
            result.put("error",new HashMap<>().put("message","could not upload this image"));
        }
        return result;
    }



    /**
     * 签名生成
     */
    @AnonymousAccess
    @PostMapping("/policy")
    @ResponseBody
    public AjaxResult policy() {
        return AjaxResult.success(cosFileService.policy());
    }


}
;