增加截图上传,图片地址优化

This commit is contained in:
2025-10-08 11:48:55 +08:00
parent 8c8af32a93
commit eed9c99357
13 changed files with 638 additions and 18 deletions

View File

@@ -210,7 +210,12 @@
<artifactId>xinge</artifactId>
<version>1.2.4.22</version>
</dependency>
<!-- 腾讯云对象存储 -->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api-bundle</artifactId>
<version>5.6.238</version>
</dependency>
<!--敏感词过滤-->
<dependency>
<groupId>com.github.houbb</groupId>

View File

@@ -1,11 +1,8 @@
package com.onekeycall.videotablet.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class CommonConfig {
public static final String ROOT_URL = "https://api.onekeycall.com";
}

View File

@@ -2,7 +2,6 @@ package com.onekeycall.videotablet.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import java.io.File;
@@ -19,6 +18,7 @@ public class FilePath {
public static final String TABLET_PATH = "tablet";
public static final String AVATAR_PATH = "avatar";
public static final String APK_ICON_PATH = "apkIcon";
public static final String SCREENSHOT_PATH = "screenshot";
public static String getRootPath() {
String osName = System.getProperty("os.name");
@@ -39,4 +39,8 @@ public class FilePath {
public static String getApkIconPath() {
return getRootPath() + File.separator + TABLET_PATH + File.separator + APK_ICON_PATH + File.separator;
}
public static String getScreenshotPath() {
return getRootPath() + File.separator + TABLET_PATH + File.separator + SCREENSHOT_PATH + File.separator;
}
}

View File

@@ -18,4 +18,7 @@ public class PushIdConfig {
public static final String CONTACT_VIDEO = "16";
public static final String CONTACT_DELETE = "17";
public static final String SCREEN_SNAPSHOT = "18";
}

View File

@@ -34,7 +34,6 @@ public class SecurityConfig {
.authorizeHttpRequests(auth -> auth
.requestMatchers("/ws/**").permitAll()
.requestMatchers("/api/ws/**", "/topic/**").permitAll()
.requestMatchers("/uploadFile/**").permitAll()
.requestMatchers("/public/**").permitAll()
// .requestMatchers("/sn/**").permitAll()
// .requestMatchers("/user/**").permitAll()
@@ -42,6 +41,8 @@ public class SecurityConfig {
.requestMatchers("/admin/**").hasRole("ADMIN")
// .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.requestMatchers("/contact/**").permitAll()
.requestMatchers("/uploadFile/**").permitAll()
.requestMatchers("/data/**").permitAll()
.anyRequest().authenticated()
);
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); // 添加JWT过滤器

View File

@@ -22,6 +22,9 @@ public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/uploadFile/**").addResourceLocations("file:uploadFile/");
registry.addResourceHandler("/uploadFile/**")
.addResourceLocations("file:uploadFile/");
registry.addResourceHandler("/data/uploads/**")
.addResourceLocations("file:/data/uploads/");
}
}

View File

@@ -1,15 +1,9 @@
package com.onekeycall.videotablet.controller.sn;
import com.onekeycall.videotablet.config.FilePath;
import com.onekeycall.videotablet.entity.ApkIconFileInfo;
import com.onekeycall.videotablet.entity.Contact;
import com.onekeycall.videotablet.entity.DeviceInfo;
import com.onekeycall.videotablet.entity.DeviceLocation;
import com.onekeycall.videotablet.entity.*;
import com.onekeycall.videotablet.result.Result;
import com.onekeycall.videotablet.service.ApkIconService;
import com.onekeycall.videotablet.service.ContactService;
import com.onekeycall.videotablet.service.DeviceLocationService;
import com.onekeycall.videotablet.service.DeviceSnService;
import com.onekeycall.videotablet.service.*;
import com.onekeycall.videotablet.utils.HashUtils;
import com.onekeycall.videotablet.utils.JwtUtil;
import com.onekeycall.videotablet.utils.TextUtils;
@@ -38,6 +32,8 @@ public class DevicesController {
private ContactService contactService;
@Autowired
private ApkIconService apkIconService;
@Autowired
private ScreenshotService screenshotService;
Logger logger = LoggerFactory.getLogger(DevicesController.class);
@@ -157,4 +153,36 @@ public class DevicesController {
return Result.ok();
}
@PostMapping("/upload_screenshot")
public Result uploadScreenshot(
@RequestPart(value = "file") MultipartFile file,
@RequestParam(value = "sn") String sn
) throws Exception {
String screenshotPath = FilePath.getScreenshotPath();
logger.info("uploadScreenshot, screenshotPath: {}", screenshotPath);
File fileDir = new File(screenshotPath);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
String originName = file.getOriginalFilename();
String fileExtension = FilenameUtils.getExtension(originName);
String hash = HashUtils.calculateMultipartFileMd5(file);
String fileName = sn + "_" + System.currentTimeMillis() + "_" + hash + "." + fileExtension;
File destFile = new File(fileDir, fileName);
try {
file.transferTo(destFile);
ScreenshotInfo screenshotInfo =new ScreenshotInfo();
screenshotInfo.setSn(sn);
screenshotInfo.setFile_name(fileName);
screenshotInfo.setUpload_time(new Date(System.currentTimeMillis()).getTime());
screenshotService.save(screenshotInfo);
} catch (Exception e) {
logger.error("uploadScreenshot error", e.getMessage());
return Result.error().message("upload screenshot error");
}
return Result.ok();
}
}

View File

@@ -46,6 +46,8 @@ public class UserController {
private DeviceApkInfoService deviceApkInfoService;
@Autowired
private ApkIconService apkIconService;
@Autowired
private ScreenshotService screenshotService;
Logger logger = LoggerFactory.getLogger(LoginController.class);
@@ -262,7 +264,7 @@ public class UserController {
) throws ExecutionException, InterruptedException {
Map<String, Object> params = new HashMap<>();
params.put("package_name", packageName);
switch (action){
switch (action) {
case "open":
DevicePushUtils.aliyunAsyncPush(PushIdConfig.OPEN_APP, sn, GsonUtils.toJSONString(params));
break;
@@ -280,4 +282,44 @@ public class UserController {
}
return Result.ok().message("success");
}
@PostMapping("/screen_snapshot")
public Result screenSnapshot(@RequestParam String sn) throws ExecutionException, InterruptedException {
Map<String, Object> params = new HashMap<>();
params.put("sn", sn);
params.put("timestamp", System.currentTimeMillis());
DevicePushUtils.aliyunAsyncPush(PushIdConfig.SCREEN_SNAPSHOT, sn, GsonUtils.toJSONString(params));
return Result.ok().message("success");
}
@GetMapping("/get_snapshot")
public Result getScreenSnapshot(@RequestParam String sn) {
List<ScreenshotInfo> screenSnapshot = screenshotService.findBySn(sn);
if (screenSnapshot == null) {
return Result.notFound().message("Screen snapshot not found");
}
return Result.ok().data(screenSnapshot);
}
@PostMapping("/delete_all_snapshot")
public Result deleteAllScreenSnapshot(@RequestParam String sn) {
screenshotService.deleteAllBySn(sn);
return Result.ok().message("success");
}
@PostMapping("/delete_snapshot")
public Result deleteScreenSnapshot(@RequestParam String sn, @RequestParam Long id) {
if (screenshotService.existsBySnAndId(sn, id)) {
boolean deleteSuccess = screenshotService.deleteBySnAndId(sn, id);
if (deleteSuccess) {
logger.info("deleteScreenSnapshot success, sn: {}, id: {}", sn, id);
} else {
logger.info("deleteScreenSnapshot fail, sn: {}, id: {}", sn, id);
}
} else {
logger.info("deleteScreenSnapshot not found, sn: {}, id: {}", sn, id);
}
return Result.ok().message("success");
}
}

View File

@@ -0,0 +1,25 @@
package com.onekeycall.videotablet.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name = "devices_snapshot")
public class ScreenshotInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id",unique = true, nullable = false)
private Long id;
@Column(name = "sn", unique = true, nullable = false)
private String sn;
@Column(name = "file_name", unique = true, nullable = false)
private String file_name;
@Column(name = "upload_time", unique = true, nullable = false)
private Long upload_time;
}

View File

@@ -77,6 +77,10 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
setUnauthorizedResponse(response, Result.unAuthorized().message("Invalid credentials"));
return; // 重要!验证失败时终止过滤器链
}
}else {
logger.error("Authorization header format error | Header: " + authorizationHeader);
setUnauthorizedResponse(response, Result.unAuthorized().message("Authorization header format error"));
return; // 重要!验证失败时终止过滤器链
}
// 如果获取到用户名且当前上下文没有认证信息
@@ -87,7 +91,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
logger.debug("Loaded user authorities: " + user.getAuthorities());
// 验证Token
if (jwtUtil.validateToken(accessToken, user,deviceId)) {
if (jwtUtil.validateToken(accessToken, user, deviceId)) {
// 创建认证令牌
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(

View File

@@ -0,0 +1,19 @@
package com.onekeycall.videotablet.repository;
import com.onekeycall.videotablet.entity.ScreenshotInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
public interface ScreenshotRepository extends JpaRepository<ScreenshotInfo, Long> {
List<ScreenshotInfo> findAllBySn(String sn);
boolean existsBySnAndId(String sn, Long id);
@Transactional
int deleteAllBySn(String sn);
@Transactional
int deleteBySnAndId(String sn, Long id);
}

View File

@@ -0,0 +1,48 @@
package com.onekeycall.videotablet.service;
import com.onekeycall.videotablet.config.CommonConfig;
import com.onekeycall.videotablet.config.FilePath;
import com.onekeycall.videotablet.entity.ScreenshotInfo;
import com.onekeycall.videotablet.repository.ScreenshotRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.function.Consumer;
@Service
public class ScreenshotService {
private final ScreenshotRepository screenshotRepository;
@Autowired
public ScreenshotService(ScreenshotRepository screenshotRepository) {
this.screenshotRepository = screenshotRepository;
}
public List<ScreenshotInfo> findBySn(String sn) {
List<ScreenshotInfo> screenshotInfos = screenshotRepository.findAllBySn(sn);
screenshotInfos.forEach(new Consumer<ScreenshotInfo>() {
@Override
public void accept(ScreenshotInfo screenshotInfo) {
screenshotInfo.setFile_name(CommonConfig.ROOT_URL + FilePath.getScreenshotPath() + screenshotInfo.getFile_name());
}
});
return screenshotInfos;
}
public void save(ScreenshotInfo screenshotInfo) {
screenshotRepository.save(screenshotInfo);
}
public boolean existsBySnAndId(String sn, Long id) {
return screenshotRepository.existsBySnAndId(sn, id);
}
public boolean deleteAllBySn(String sn) {
return screenshotRepository.deleteAllBySn(sn) > 0;
}
public boolean deleteBySnAndId(String sn, Long id) {
return screenshotRepository.deleteBySnAndId(sn, id) > 0;
}
}

View File

@@ -0,0 +1,441 @@
package com.onekeycall.videotablet.tencent.cos;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
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.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.CopyObjectRequest;
import com.qcloud.cos.model.CopyResult;
import com.qcloud.cos.model.GetObjectRequest;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.UploadResult;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.transfer.Copy;
import com.qcloud.cos.transfer.Download;
import com.qcloud.cos.transfer.MultipleFileDownload;
import com.qcloud.cos.transfer.MultipleFileUpload;
import com.qcloud.cos.transfer.PersistableDownload;
import com.qcloud.cos.transfer.PersistableUpload;
import com.qcloud.cos.transfer.Transfer;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.TransferManagerConfiguration;
import com.qcloud.cos.transfer.TransferProgress;
import com.qcloud.cos.transfer.Upload;
// TransferManager提供异步的上传文件, 下载文件copy文件的高级API接口
// 可以根据文件大小自动的选择上传接口或者copy接口,方便用户使用, 无需自行封装较复杂的分块上传或者分块copy
public class TransferManagerDemo {
private static String secretId = System.getenv("SECRETID");
private static String secretKey = System.getenv("SECRETKEY");
private static String cosRegion = System.getenv("REGION");
private static String bucketName = System.getenv("BUCKET_NAME");
public static void main(String[] args) {
//multipartUploadWithMetaData();
resumableDownloadFile();
}
private static TransferManager createTransferManager() {
// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region(cosRegion));
clientConfig.setHttpProtocol(HttpProtocol.https);
// 3 生成cos客户端
COSClient cosclient = new COSClient(cred, clientConfig);
ExecutorService threadPool = Executors.newFixedThreadPool(32);
// 传入一个threadpool, 若不传入线程池, 默认TransferManager中会生成一个单线程的线程池。
TransferManager transferManager = new TransferManager(cosclient, threadPool);
return transferManager;
}
// Prints progress while waiting for the transfer to finish.
private static void showTransferProgress(Transfer transfer) {
System.out.println(transfer.getDescription());
do {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
return;
}
TransferProgress progress = transfer.getProgress();
long so_far = progress.getBytesTransferred();
long total = progress.getTotalBytesToTransfer();
double pct = progress.getPercentTransferred();
System.out.printf("[%d / %d] = %.02f%%\n", so_far, total, pct);
} while (transfer.isDone() == false);
System.out.println(transfer.getState());
}
// 上传文件, 根据文件大小自动选择简单上传或者分块上传。
private static void uploadFile() {
TransferManager transferManager = createTransferManager();
String key = "aaa/bbb.txt";
File localFile = new File("src/test/resources/len30M.txt");
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
try {
// 返回一个异步结果Upload, 可同步的调用waitForUploadResult等待upload结束, 成功返回UploadResult, 失败抛出异常.
long startTime = System.currentTimeMillis();
Upload upload = transferManager.upload(putObjectRequest);
showTransferProgress(upload);
UploadResult uploadResult = upload.waitForUploadResult();
long endTime = System.currentTimeMillis();
System.out.println("used time: " + (endTime - startTime) / 1000);
System.out.println(uploadResult.getETag());
System.out.println(uploadResult.getCrc64Ecma());
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
}
// 上传文件(上传过程中暂停, 并继续上传)
private static void pauseUploadFileAndResume() {
TransferManager transferManager = createTransferManager();
String key = "aaa/bbb.txt";
File localFile = new File("src/test/resources/len30M.txt");
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
try {
// 返回一个异步结果Upload, 可同步的调用waitForUploadResult等待upload结束, 成功返回UploadResult, 失败抛出异常.
Upload upload = transferManager.upload(putObjectRequest);
Thread.sleep(10000);
PersistableUpload persistableUpload = upload.pause();
upload = transferManager.resumeUpload(persistableUpload);
showTransferProgress(upload);
UploadResult uploadResult = upload.waitForUploadResult();
System.out.println(uploadResult.getETag());
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
}
private static void multipartUploadWithMetaData() {
TransferManager transferManager = createTransferManager();
String key = "aaa/bbb.txt";
File localFile = new File("src/test/resources/len20M.txt");
ObjectMetadata objectMetadata = new ObjectMetadata();
Map<String, String> userMeta = new HashMap<String, String>();
userMeta.put("usermeta", "hello-mult");
objectMetadata.setUserMetadata(userMeta);
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
putObjectRequest.withMetadata(objectMetadata);
try {
// 返回一个异步结果Upload, 可同步的调用waitForUploadResult等待upload结束, 成功返回UploadResult, 失败抛出异常.
long startTime = System.currentTimeMillis();
Upload upload = transferManager.upload(putObjectRequest);
//showTransferProgress(upload);
UploadResult uploadResult = upload.waitForUploadResult();
long endTime = System.currentTimeMillis();
System.out.println("used time: " + (endTime - startTime) / 1000);
System.out.println(uploadResult.getETag());
System.out.println(uploadResult.getCrc64Ecma());
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
}
// 批量上传
private static void uploadDirectory() {
TransferManager transferManager = createTransferManager();
// 设置文件上传到 bucket 之后的前缀目录,设置为 “”,表示上传到 bucket 的根目录
String cos_path = "/prefix";
// 要上传的文件夹的绝对路径
String dir_path = "/to/mydir";
// 是否递归上传目录下的子目录,如果是 true子目录下的文件也会上传且cos上会保持目录结构
Boolean recursive = false;
try {
// 返回一个异步结果Upload, 可同步的调用waitForUploadResult等待upload结束, 成功返回UploadResult, 失败抛出异常.
MultipleFileUpload upload = transferManager.uploadDirectory(bucketName, cos_path, new File(dir_path), recursive);
// 可以选择查看上传进度
showTransferProgress(upload);
// 或者阻塞等待完成
upload.waitForCompletion();
System.out.println("upload directory done.");
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
}
// 批量下载
private static void downloadDirectory() {
TransferManager transferManager = createTransferManager();
// 设置要下载的对象的前缀相当于cos上的一个目录如果设置成 "",则下载整个 bucket。
String cos_path = "/prefix";
// 要保存下载的文件的文件夹的绝对路径
String dir_path = "/to/mydir";
try {
// 返回一个异步结果download, 可同步的调用waitForUploadResult等待download结束.
MultipleFileDownload download = transferManager.downloadDirectory(bucketName, cos_path, new File(dir_path));
// 可以选择查看下载进度
showTransferProgress(download);
// 或者阻塞等待完成
download.waitForCompletion();
System.out.println("download directory done.");
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
}
// 将文件下载到本地
private static void downLoadFile() {
TransferManager transferManager = createTransferManager();
String key = "aaa/bbb.txt";
File downloadFile = new File("src/test/resources/download.txt");
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key);
try {
// 返回一个异步结果copy, 可同步的调用waitForCompletion等待download结束, 成功返回void, 失败抛出异常.
Download download = transferManager.download(getObjectRequest, downloadFile);
download.waitForCompletion();
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
}
// 将文件下载到本地(中途暂停并继续开始)
private static void pauseDownloadFileAndResume() {
TransferManager transferManager = createTransferManager();
String key = "aaa/bbb.txt";
File downloadFile = new File("src/test/resources/download.txt");
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key);
try {
// 返回一个异步结果copy, 可同步的调用waitForCompletion等待download结束, 成功返回void, 失败抛出异常.
Download download = transferManager.download(getObjectRequest, downloadFile);
Thread.sleep(5000L);
PersistableDownload persistableDownload = download.pause();
download = transferManager.resumeDownload(persistableDownload);
showTransferProgress(download);
download.waitForCompletion();
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
}
// copy接口支持根据文件大小自动选择copy或者分块copy
// 以下代码展示跨园区拷贝, 即将一个园区的文件拷贝到另一个园区
private static void copyFileForDiffRegion() {
// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region(cosRegion));
// 3 生成cos客户端
COSClient cosclient = new COSClient(cred, clientConfig);
ExecutorService threadPool = Executors.newFixedThreadPool(32);
// 传入一个threadpool, 若不传入线程池, 默认TransferManager中会生成一个单线程的线程池。
TransferManager transferManager = new TransferManager(cosclient, threadPool);
// 要拷贝的bucket region, 支持跨园区拷贝
Region srcBucketRegion = new Region("ap-shanghai");
// 源bucket, bucket名需包含appid
String srcBucketName = "srcBucket-12500000000";
// 要拷贝的源文件
String srcKey = "aaa/bbb.txt";
// 目的bucket, bucket名需包含appid
String destBucketName = "destBucket-12500000000";
// 要拷贝的目的文件
String destKey = "ccc/ddd.txt";
COSClient srcCOSClient = new COSClient(cred, new ClientConfig(srcBucketRegion));
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(srcBucketRegion, srcBucketName,
srcKey, destBucketName, destKey);
try {
Copy copy = transferManager.copy(copyObjectRequest, srcCOSClient, null);
// 返回一个异步结果copy, 可同步的调用waitForCopyResult等待copy结束, 成功返回CopyResult, 失败抛出异常.
CopyResult copyResult = copy.waitForCopyResult();
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
srcCOSClient.shutdown();
cosclient.shutdown();
}
// copy接口支持根据文件大小自动选择copy或者分块copy
// 以下代码展示同园区拷贝, 即将同园区的文件拷贝到另一个园区
private static void copyFileForSameRegion() {
TransferManager transferManager = createTransferManager();
TransferManagerConfiguration transferManagerConfiguration = new TransferManagerConfiguration();
transferManagerConfiguration.setMultipartCopyThreshold(20*1024*1024);
transferManager.setConfiguration(transferManagerConfiguration);
// 要拷贝的bucket region, 支持跨园区拷贝
Region srcBucketRegion = new Region("ap-beijing-1");
// 源bucket, bucket名需包含appid
String srcBucketName = "srcBucket-12500000000";
// 要拷贝的源文件
String srcKey = "aaa/bbb.txt";
// 目的bucket, bucket名需包含appid
String destBucketName = "destBucket-12500000000";
// 要拷贝的目的文件
String destKey = "ccc/ddd.txt";
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(srcBucketRegion, srcBucketName,
srcKey, destBucketName, destKey);
try {
Copy copy = transferManager.copy(copyObjectRequest);
// 返回一个异步结果copy, 可同步的调用waitForCopyResult等待copy结束, 成功返回CopyResult, 失败抛出异常.
CopyResult copyResult = copy.waitForCopyResult();
System.out.println(copyResult.getCrc64Ecma());
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
}
private static void copyFileSetMetadata() {
// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region(cosRegion));
// 3 生成cos客户端
COSClient cosclient = new COSClient(cred, clientConfig);
ClientConfig srcClientConfig = new ClientConfig(new Region("ap-shanghai"));
COSClient srcCosclient = new COSClient(cred, srcClientConfig);
ExecutorService threadPool = Executors.newFixedThreadPool(2);
// 传入一个threadpool, 若不传入线程池, 默认TransferManager中会生成一个单线程的线程池。
TransferManager transferManager = new TransferManager(cosclient, threadPool);
TransferManagerConfiguration transferManagerConfiguration = new TransferManagerConfiguration();
transferManagerConfiguration.setMultipartCopyThreshold(5*1024*1024);
transferManager.setConfiguration(transferManagerConfiguration);
// 要拷贝的bucket region, 支持跨园区拷贝
Region srcBucketRegion = new Region("ap-shanghai");
// 源bucket, bucket名需包含appid
String srcBucketName = "mysrcbucket-123456789";
// 要拷贝的源文件
String srcKey = "aaa/bbb.txt";
// 目的bucket, bucket名需包含appid
String destBucketName = "mydestbucekt-123456789";
// 要拷贝的目的文件
String destKey = "bbb/ccc.txt";
ObjectMetadata objectMetadata = new ObjectMetadata();
Map<String, String> userMeta = new HashMap<String, String>();
userMeta.put("usermeta", "hello-mult-copy");
objectMetadata.setUserMetadata(userMeta);
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(srcBucketRegion, srcBucketName,
srcKey, destBucketName, destKey);
System.out.println(copyObjectRequest.getDestinationBucketName());
copyObjectRequest.setNewObjectMetadata(objectMetadata);
try {
Copy copy = transferManager.copy(copyObjectRequest, srcCosclient, null);
// 返回一个异步结果copy, 可同步的调用waitForCopyResult等待copy结束, 成功返回CopyResult, 失败抛出异常.
//showTransferProgress(copy);
CopyResult copyResult = copy.waitForCopyResult();
System.out.println(copyResult.getCrc64Ecma());
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
cosclient.shutdown();
}
private static void resumableDownloadFile() {
TransferManager transferManager = createTransferManager();
GetObjectRequest getObj = new GetObjectRequest(bucketName, "/path/to/key");
File dstFile = new File("dstFile");
Download download = transferManager.download(getObj, dstFile, true);
showTransferProgress(download);
try {
download.waitForCompletion();
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
transferManager.shutdownNow();
}
}