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());
}
}