2026 JAVA 文件或者base64上传到腾讯云的cos的工具类
2026 JAVA 文件或者base64上传到腾讯云的cos中
·
腾讯云官方API网址
https://cloud.tencent.com/document/api/436/7751
1、pom依赖
<!--hutool工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M2</version>
</dependency>
<!-- 腾讯云 -->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.155</version>
</dependency>
2、工具类TencentCOSUtil
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
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.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Base64;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component
public class TencentCOSUtil {
// COS的SecretId
private static String SECRET_ID = "自己的SecretId";
// COS的SecretKey
private static String SECRET_KEY = "自己的SecretKey";
//https://存储桶名称-1303******.cos.地域全拼.myqcloud.com/
private static String ROOT_SRC = "https://存储桶名称-1303******.cos.地域全拼.myqcloud.com/";
// 上传的存储桶的地域,可参考在COS的后台能查询,示例:ap-beijing
private static String BUCKET_ADDR = "地域全拼";
// 存储桶的名字
private static String BUCKET_NAME = "自己的存储桶名称";
/**
* 1.调用静态方法getCosClient()就会获得COSClient实例
* 2.本方法根据永久密钥初始化 COSClient的,官方是不推荐,官方推荐使用临时密钥,是可以限制密钥使用权限,创建cred时有些区别
*
* @return COSClient实例
*/
private static COSClient getCosClient() {
// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(SECRET_ID, SECRET_KEY);
// 2.1 设置存储桶的地域(上文获得)
Region region = new Region(BUCKET_ADDR);
ClientConfig clientConfig = new ClientConfig(region);
// 2.2 使用https协议传输
clientConfig.setHttpProtocol(HttpProtocol.https);
// 3 生成 cos 客户端
COSClient cosClient = new COSClient(cred, clientConfig);
// 返回COS客户端
return cosClient;
}
/**
* 上传文件
*
* @param file
* @return 返回文件的url
*/
public static String upLoadFile(MultipartFile file) {
try {
// 获取上传的文件的输入流
InputStream inputStream = file.getInputStream();
// 避免文件覆盖,获取文件的原始名称,如123.jpg,然后通过截取获得文件的后缀,也就是文件的类型
String originalFilename = file.getOriginalFilename();
// 获取文件的类型
String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
// 使用UUID工具 创建唯一名称,放置文件重名被覆盖,在拼接上上命令获取的文件类型
String fileName = UUID.randomUUID().toString() + fileType;
// 指定文件上传到 COS 上的路径,即对象键最终文件会传到存储桶名字中的images文件夹下的fileName名字
String key = "自定义路径/" + fileName;
// 创建上传Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
// - 使用输入流存储,需要设置请求长度
objectMetadata.setContentLength(inputStream.available());
// - 设置缓存
objectMetadata.setCacheControl("no-cache");
// - 设置Content-Type
objectMetadata.setContentType(fileType);
// 上传文件
PutObjectResult putResult = getCosClient().putObject(BUCKET_NAME, key, inputStream, objectMetadata);
// 创建文件的网络访问路径
String url = ROOT_SRC + DateUtil.today() + "/" + key;
// 关闭 cosClient,并释放 HTTP 连接的后台管理线程
getCosClient().shutdown();
return url;
} catch (Exception e) {
e.printStackTrace();
// 发生IO异常、COS连接异常等,返回空
return null;
}
}
/**
* 上传Base64图片
*
* @param base64Data base64编码的图片数据(可以包含data:image/png;base64,前缀)
* @return 返回文件的url,上传失败返回null
*/
public static String upLoadBase64Image(String base64Data) {
return upLoadBase64Image(base64Data, null);
}
/**
* 上传Base64图片
*
* @param base64Data base64编码的图片数据(可以包含data:image/png;base64,前缀)
* @param fileName 自定义文件名(不包含扩展名),如果为null则使用UUID生成
* @return 返回文件的url,上传失败返回null
*/
public static String upLoadBase64Image(String base64Data, String fileName) {
COSClient cosClient = null;
try {
// 验证base64数据
if (StrUtil.isBlank(base64Data)) {
return null;
}
// 清理base64数据(移除可能的data:image/png;base64,前缀)
String cleanedBase64 = cleanBase64Data(base64Data);
if (StrUtil.isBlank(cleanedBase64)) {
return null;
}
// 解码base64数据
byte[] imageBytes = Base64.getDecoder().decode(cleanedBase64);
// 根据base64前缀或文件扩展名确定文件类型
String fileType = getFileTypeFromBase64(base64Data);
if (fileType == null) {
// 如果没有找到明确的文件类型,尝试从数据内容判断(简单判断)
fileType = detectImageType(imageBytes);
if (fileType == null) {
fileType = ".jpg"; // 默认使用jpg
}
}
// 生成文件名
if (StrUtil.isBlank(fileName)) {
fileName = UUID.randomUUID().toString();
}
String fullFileName = fileName + fileType;
// 指定文件上传到 COS 上的路径
// images/2026-01-01/xxx
String key = "自定义路径名称/"+DateUtil.today()+"/" + fullFileName;
// 创建输入流
InputStream inputStream = new ByteArrayInputStream(imageBytes);
// 创建上传Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(imageBytes.length);
objectMetadata.setCacheControl("no-cache");
objectMetadata.setContentType(getContentType(fileType));
// 获取COS客户端
cosClient = getCosClient();
// 上传文件
PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, key, inputStream, objectMetadata);
cosClient.putObject(putObjectRequest);
// 创建文件的网络访问路径
String url = ROOT_SRC + key;
return url;
} catch (Exception e) {
e.printStackTrace();
// 发生异常,返回空
return null;
} finally {
// 关闭cosClient
if (cosClient != null) {
cosClient.shutdown();
}
}
}
/**
* 清理base64数据,移除data:image/png;base64,前缀
*
* @param base64Data 原始base64数据
* @return 清理后的base64数据
*/
private static String cleanBase64Data(String base64Data) {
if (base64Data.contains("base64,")) {
return base64Data.substring(base64Data.indexOf("base64,") + 7);
}
return base64Data;
}
/**
* 从base64数据中获取文件类型
*
* @param base64Data base64数据
* @return 文件扩展名,如 ".jpg", ".png" 等
*/
private static String getFileTypeFromBase64(String base64Data) {
// 匹配data:image/类型;base64,格式
Pattern pattern = Pattern.compile("data:image/(.*?);base64,");
Matcher matcher = pattern.matcher(base64Data);
if (matcher.find()) {
String imageType = matcher.group(1).toLowerCase();
switch (imageType) {
case "jpeg":
case "jpg":
return ".jpg";
case "png":
return ".png";
case "gif":
return ".gif";
case "bmp":
return ".bmp";
case "webp":
return ".webp";
case "svg+xml":
return ".svg";
default:
return "." + imageType;
}
}
return null;
}
/**
* 根据字节数据检测图片类型
*
* @param bytes 图片字节数据
* @return 文件扩展名
*/
private static String detectImageType(byte[] bytes) {
if (bytes.length < 4) {
return null;
}
// 检查PNG
if (bytes[0] == (byte) 0x89 && bytes[1] == (byte) 0x50 &&
bytes[2] == (byte) 0x4E && bytes[3] == (byte) 0x47) {
return ".png";
}
// 检查JPEG
if (bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xD8) {
return ".jpg";
}
// 检查GIF
if (bytes[0] == (byte) 0x47 && bytes[1] == (byte) 0x49 &&
bytes[2] == (byte) 0x46 && bytes[3] == (byte) 0x38) {
return ".gif";
}
// 检查BMP
if (bytes[0] == (byte) 0x42 && bytes[1] == (byte) 0x4D) {
return ".bmp";
}
// 检查WEBP
if (bytes[0] == (byte) 0x52 && bytes[1] == (byte) 0x49 &&
bytes[2] == (byte) 0x46 && bytes[3] == (byte) 0x46) {
if (bytes.length >= 12 && bytes[8] == (byte) 0x57 &&
bytes[9] == (byte) 0x45 && bytes[10] == (byte) 0x42 &&
bytes[11] == (byte) 0x50) {
return ".webp";
}
}
return null;
}
/**
* 根据文件扩展名获取Content-Type
*
* @param fileType 文件扩展名
* @return Content-Type字符串
*/
private static String getContentType(String fileType) {
switch (fileType.toLowerCase()) {
case ".jpg":
case ".jpeg":
return "image/jpeg";
case ".png":
return "image/png";
case ".gif":
return "image/gif";
case ".bmp":
return "image/bmp";
case ".webp":
return "image/webp";
case ".svg":
return "image/svg+xml";
default:
return "application/octet-stream";
}
}
}
更多推荐
所有评论(0)