SpringBoot项目集成亚马逊的S3对象存储

pom文件导入依赖

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.amazonaws</groupId>
                <artifactId>aws-java-sdk-bom</artifactId>
                <version>1.12.642</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>
<dependencies>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
        </dependency>
</dependencies>

yml配置:
aws:
  accessKey: xxxxxx
  secretKey: xxxxxx
  endPoint: http://10.10.10.1:443
  bucketName: bucket-test01
组装客户端Service
package com.susu.service;

import com.amazonaws.services.s3.model.CompleteMultipartUploadResult;
import com.amazonaws.services.s3.model.PutObjectResult;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;

public interface EdsOssFileUploadService {

	/**
	 * 高级API大文件分片上传
	 * @param keyName 唯一文件标识
	 * @param file file
	 * @return keyName 唯一文件标识
	 * @throws InterruptedException
	 */
	String highLevelMultipartUpload(String keyName, File file) throws InterruptedException;


	/**
	 * 文件分片上传
	 * @param keyName 唯一文件标识
	 * @param bucketName 桶名称
	 * @param file file
	 * @return CompleteMultipartUploadResult
	 */
	CompleteMultipartUploadResult bigFileListShardingUpload(String keyName, String bucketName, File file);


	/**
	 * 文件分片上传
	 * @param keyName 唯一文件标识
	 * @param file file
	 * @return CompleteMultipartUploadResult
	 */
	CompleteMultipartUploadResult bigFileListShardingUpload(String keyName, File file);


	/**
	 *  文件分片上传 指定桶
	 * @param bucketName 桶名称
	 * @param fileInputStream 文件流
	 * @param fileContentLength  原始文件的length
	 * @param keyName 唯一文件标识
	 * @return CompleteMultipartUploadResult
	 */
	CompleteMultipartUploadResult uploadLargeFileToS3(String bucketName, FileInputStream fileInputStream, long fileContentLength, String keyName);


	/**
	 *  文件分片上传 默认桶
	 * @param fileInputStream 文件流
	 * @param fileLength 原始文件的length
	 * @param key 唯一文件标识
	 * @return CompleteMultipartUploadResult
	 */
	CompleteMultipartUploadResult uploadLargeFileToS3(FileInputStream fileInputStream, long fileLength, String key);

	/**
	 * 文件下载
	 * @param key 唯一文件标识
	 * @param bucketName  桶名称
	 * @return InputStream
	 */
	InputStream downloadToEDS(String key, String bucketName);


	/**
	 * 文件下载  默认桶
	 * @param key 唯一文件标识
	 * @return InputStream
	 */
	InputStream downloadToEDS(String key);


	/**
	 * 简单文件上传 --流 指定桶
	 * @param keyName 唯一文件标识
	 * @param inputStream 文件流
	 * @param bucketName 桶名称
	 * @return PutObjectResult
	 */
	PutObjectResult streamUploadToEDS(String keyName, InputStream inputStream, String bucketName);


	/**
	 * 简单文件上传 --流 默认桶
	 * @param keyName 唯一文件标识
	 * @param inputStream 文件流
	 * @return PutObjectResult
	 */
	PutObjectResult streamUploadToEDS(String keyName, InputStream inputStream);


	/**
	 *  简单文件上传 --file 指定桶
	 * @param keyName 唯一文件标识
	 * @param file 文件
	 * @param bucketName 桶名称
	 * @return PutObjectResult
	 */
	PutObjectResult simpleUploadToEDS(String keyName, File file, String bucketName);


	/**
	 *  简单文件上传 --file 默认桶
	 * @param keyName 唯一文件标识
	 * @param file 文件
	 * @return PutObjectResult
	 */
	PutObjectResult simpleUploadToEDS(String keyName, File file);

	/**
	 * 创建文件上传的预签名--URL
	 * @param bucketName 桶名称
	 * @param keyName 唯一文件标识
	 * @return URL
	 */
	URL createSignedUrlForStringPut(String bucketName, String keyName);

	/**
	 * 创建文件下载的预签名--URL
	 * @param bucketName 桶名称
	 * @param keyName 唯一文件标识
	 * @return URL
	 */
	URL createSignedUrlForStringGet(String bucketName, String keyName);
}

组装客户端Impl
package com.susu.service.impl;

import cn.hutool.core.util.IdUtil;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.HttpMethod;
import com.amazonaws.Protocol;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
import com.amazonaws.services.s3.transfer.Upload;
import com.amazonaws.services.s3.transfer.model.UploadResult;
import com.susu.service.EdsOssFileUploadService;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.amazonaws.retry.RetryPolicy;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

@Service
@Data
public class EdsOssFileUploadServiceImpl implements EdsOssFileUploadService {
	private Logger logger = LoggerFactory.getLogger(EdsOssFileUploadServiceImpl.class);

	/**
	 * access key :示例L8O3KRQZTXGVDIBQ0WON
	 */
	@Value("${aws.accessKey}")
	private String accessKey;


	/**
	 * secret key:示例Bm0kLoFdLu70RKTOtjdP5Q9oOVDgEXHOmbrelxeb
	 */
	@Value("${aws.secretKey}")
	private String secretKey;

	/**
	 * 地址:对象存储服务的端口号:示例http://10.212.27.56:12001
	 */
	@Value("${aws.endPoint}")
	private String endPoint;

	/**
	 * bucket名称:示例eds-cloud-oss
	 */
	@Value("${aws.bucketName}")
	private String bucketName;

	/**
	 * region:示例cn-north-1
	 */
	/*@Value("${aws.region}")
	private String region;*/

	private AmazonS3 amazonS3Client;


	private TransferManager transferManager;

	@Autowired
	@Qualifier("asyncTaskExecutor")
	private Executor threadPoolTaskExecutor;

	@PostConstruct
	public void init() {
		AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
		ClientConfiguration clientConfig = new ClientConfiguration();
		clientConfig.setSignerOverride("AWSS3V4SignerType");
		clientConfig.setProtocol(Protocol.HTTP);
		clientConfig.setConnectionTimeout(300000);
		clientConfig.setClientExecutionTimeout(300000);
		clientConfig.setConnectionMaxIdleMillis(300000);
		clientConfig.setRetryPolicy(new RetryPolicy(null,null,3,true));

		// 初始化AmazonS3Client
		this.amazonS3Client = AmazonS3ClientBuilder.standard()
			.withClientConfiguration(clientConfig)
			.withCredentials(new AWSStaticCredentialsProvider(credentials))
			.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, ""))
			.withPathStyleAccessEnabled(true).build();

		// 配置自定义线程池
		int availableProcessor = Runtime.getRuntime().availableProcessors();
		ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
			availableProcessor + 1,
			(availableProcessor + 1) * 2,
			60,  // 非核心线程空闲时间
			TimeUnit.SECONDS,
			new ArrayBlockingQueue<Runnable>(200),
			new ThreadPoolExecutor.CallerRunsPolicy());
		this.transferManager = TransferManagerBuilder.standard()
			.withS3Client(amazonS3Client)
			.withExecutorFactory(()-> threadPool)
			.build();
	}


	/**
	 * AWS SDK 公开了一个名为 TransferManager 的高级别 API,用于简化分段上传。有关更多信息,请参阅 使用分段上传来上传和复制对象。
	 * <p>
	 * 您可以从文件或流上传数据。您还可以设置高级选项,例如,您想要用于分段上传的分段大小或在上传分段时要使用的并发线程数。
	 * 您也可以设置可选的对象属性、存储类或访问控制列表 (ACL)。您可以使用 PutObjectRequest 和 TransferManagerConfiguration 类来设置这些高级选项。
	 *
	 * @param keyName keyName
	 * @param file    file
	 * @return CompleteMultipartUploadResult
	 */
	@Override
	public String highLevelMultipartUpload(String keyName, File file) {
		// 使用 TransferManager 上传
		try {
			Upload upload = transferManager.upload(bucketName, keyName, file);
			upload.waitForCompletion();
			String url = amazonS3Client.getUrl(bucketName, keyName).toString();
			logger.info("上传文件完成,地址:{}", url);
			return url;
		}catch (Exception e ){
			logger.error("上传文件异常:{}",e);
		}
		return null;
	}


	/**
	 * EDS提供的分片上传(Multipart Upload)功能,将要上传的较大文件(object)分成多个分片(Part)来分别上传
	 * 上传完成后再调用completeMultipartUpload接口将这些Part组合成一个object来达到断点续传的效果。
	 *
	 * @param keyName    keyName
	 * @param bucketName yourBucketName
	 * @param file       file
	 * @return CompleteMultipartUploadResult
	 */
	@Override
	public CompleteMultipartUploadResult bigFileListShardingUpload(String keyName, String bucketName, File file) {
		List<PartETag> partETags = new ArrayList<>();
		long filePosition = 0;
		CompleteMultipartUploadResult result = null;
		String uploadId = null;
		InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(bucketName, keyName);
		InitiateMultipartUploadResult initResponse = amazonS3Client.initiateMultipartUpload(initRequest);
		uploadId = initResponse.getUploadId();
		try {
			long contentLength = file.length();
			long partSize = 25 * 1024 * 1024; // Set part size to 25 MB.
			logger.info("-------开始只能进入分片上传阶段-------");
			for (int i = 1; filePosition < contentLength; i++) {
				partSize = Math.min(partSize, (contentLength - filePosition));
				UploadPartRequest uploadRequest = new UploadPartRequest().withBucketName(bucketName).withKey(keyName).withUploadId(uploadId).withPartNumber(i).withFileOffset(filePosition).withFile(file).withPartSize(partSize);
				UploadPartResult uploadResult = amazonS3Client.uploadPart(uploadRequest);
				// 返回文件的ETag值,用于验证文件是否被正确上传
				partETags.add(uploadResult.getPartETag());
				filePosition += partSize;
				logger.info("文件分片上传--->" + filePosition);
			}
			logger.info("-------所有分片上传完整------->进入分片合并阶段-------");
			// 完成分片上传
			CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(bucketName, keyName, initResponse.getUploadId(), partETags);
			result = amazonS3Client.completeMultipartUpload(compRequest);
			logger.info("Object upload complete,地址:{}",result.getLocation().toString());
		} catch (SdkClientException e) {
			logger.error("分片上传错误,第{}片发生意外", filePosition, e);
			throw new RuntimeException(e);
		}
		logger.info("-------大文件分片上传完成--->" + filePosition);
		return result;
	}

	@Override
	public CompleteMultipartUploadResult bigFileListShardingUpload(String keyName, File file) {
		return bigFileListShardingUpload(keyName, bucketName, file);
	}

	/**
	 * 分片上传
	 *
	 * @param bucketName        桶名称
	 * @param fileInputStream   文件流
	 * @param fileContentLength 原始文件的length
	 * @param keyName           唯一文件标识
	 * @return
	 */
	@Override
	public CompleteMultipartUploadResult uploadLargeFileToS3(String bucketName, FileInputStream fileInputStream, long fileContentLength, String keyName) {
		InitiateMultipartUploadResult initResponse = null;
		InitiateMultipartUploadRequest initRequest = null;
		CompleteMultipartUploadResult completeMultipartUploadResult = null;
		try {
			// 初始化多部分上传
			initRequest = new InitiateMultipartUploadRequest(bucketName, keyName);
			initResponse = amazonS3Client.initiateMultipartUpload(initRequest);
			// 每个分片大小(例如:5MB)
			long partSize = 5 * 1024 * 1024;

			List<PartETag> partETags = new ArrayList<>();
			long bytePosition = 0;

			for (int i = 1; bytePosition < fileContentLength; i++) {
				long bytesRemaining = fileContentLength - bytePosition;
				partSize = Math.min(bytesRemaining, partSize);

				UploadPartRequest uploadRequest = new UploadPartRequest().withBucketName(bucketName).withKey(keyName).withUploadId(initResponse.getUploadId()).withPartNumber(i).withFileOffset(bytePosition).withInputStream(fileInputStream).withPartSize(partSize);

				UploadPartResult uploadResult = amazonS3Client.uploadPart(uploadRequest);
				partETags.add(uploadResult.getPartETag());
				bytePosition += partSize;
			}
			// 完成多部分上传
			CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(bucketName, keyName, initResponse.getUploadId(), partETags);
			completeMultipartUploadResult = amazonS3Client.completeMultipartUpload(compRequest);
		} catch (SdkClientException e) {
			// 处理异常,可能需要回滚已上传的部分
			logger.error("Error uploading file to S3", e);
			// 如果有错误,尝试取消上传
			AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest(bucketName, keyName, initResponse.getUploadId());
			amazonS3Client.abortMultipartUpload(abortMPURequest);
		} finally {
			try {
				fileInputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return completeMultipartUploadResult;
	}

	@Override
	public CompleteMultipartUploadResult uploadLargeFileToS3(FileInputStream fileInputStream, long fileLength, String key) {
		return uploadLargeFileToS3(bucketName, fileInputStream, fileLength, key);
	}

	/**
	 * 简单下载文件流
	 *
	 * @param key key
	 * @return InputStream
	 */
	@Override
	public InputStream downloadToEDS(String key, String bucketName) {
		logger.info("Downloading {} from S3 bucket {}...\n", key, bucketName);
		S3Object object = amazonS3Client.getObject(new GetObjectRequest(bucketName, key));
		return object.getObjectContent();
	}

	@Override
	public InputStream downloadToEDS(String key) {
		return downloadToEDS(key, bucketName);
	}


	/**
	 * 流式上传文件到EDS
	 *
	 * @param keyName     fileName
	 * @param inputStream InputStream
	 * @return PutObjectResult
	 */
	@Override
	public PutObjectResult streamUploadToEDS(String keyName, InputStream inputStream, String bucketName) {
		try {
			//创建上传Object的Metadata
			ObjectMetadata metadata = new ObjectMetadata();
			//上传的文件的长度
			metadata.setContentLength(inputStream.available());
			//指定该Object被下载时的网页的缓存行为
			metadata.setCacheControl("no-cache");
			//指定该Object下设置Header
			metadata.setHeader("Pragma", "no-cache");
			//指定该Object被下载时的内容编码格式
			metadata.setContentEncoding("utf-8");
			//文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
			//如果没有扩展名则填默认值application/octet-stream
			metadata.setContentType("application/octet-stream");
			return amazonS3Client.putObject(bucketName, keyName, inputStream, metadata);
		} catch (IOException e) {
			logger.error("文件上传失败。。。。" + e.getMessage());
			throw new RuntimeException(e);
		} catch (SdkClientException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public PutObjectResult streamUploadToEDS(String keyName, InputStream inputStream) {
		return streamUploadToEDS(keyName, inputStream, bucketName);
	}


	/**
	 * 简单上传文件到EDS
	 *
	 * @param keyName fileName
	 * @param file    file
	 * @return PutObjectResult
	 */
	@Override
	public PutObjectResult simpleUploadToEDS(String keyName, File file, String bucketName) {
		return amazonS3Client.putObject(bucketName, keyName, file);
	}

	@Override
	public PutObjectResult simpleUploadToEDS(String keyName, File file) {
		return amazonS3Client.putObject(bucketName, keyName, file);
	}

	/**
	 * 创建文件上传的预签名--URL
	 *
	 * @param bucketName 桶名称
	 * @param keyName    唯一文件标识
	 * @return URL
	 */
	@Override
	public URL createSignedUrlForStringPut(String bucketName, String keyName) {
		Date expiration = new Date();
		long expirationNumber = expiration.getTime() + 3600 * 1000;
		expiration.setTime(expirationNumber);
		GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, keyName, HttpMethod.PUT);
		generatePresignedUrlRequest.setExpiration(expiration);
		return amazonS3Client.generatePresignedUrl(generatePresignedUrlRequest);
	}

	/**
	 * 创建文件下载的预签名--URL
	 *
	 * @param bucketName 桶名称
	 * @param keyName    唯一文件标识
	 * @return URL
	 */
	@Override
	public URL createSignedUrlForStringGet(String bucketName, String keyName) {
		Date expiration = new Date();
		long expirationNumber = expiration.getTime() + 3600 * 1000;
		expiration.setTime(expirationNumber);
		GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, keyName, HttpMethod.GET);
		generatePresignedUrlRequest.setExpiration(expiration);
		return amazonS3Client.generatePresignedUrl(generatePresignedUrlRequest);
	}
}
SpringBoot测试
@SpringBootTest(classes = FilestoreApplication.class)
@Import(EdsOssFileUploadServiceImpl.class)
public class FilestoreApplicationTest {
    private Logger logger = LoggerFactory.getLogger(FilestoreApplicationTest.class);
    @Autowired
    private EdsOssFileUploadService edsOssFileUploadService;

    /**
     * 文件上传EDS云对象存储测试:通过
     * <p>
     * 2024-03-06 14:07:03.079  INFO 15144 --- [           main] c.c.c.f.FilestoreApplicationTest         : Started FilestoreApplicationTest in 2.059 seconds (JVM running for 2.728)
     * 2024-03-06 14:07:03.270  INFO 15144 --- [           main] c.c.c.f.FilestoreApplicationTest         : 上传生成的=26438e0c-e379-4343-b645-03e8056baaf6/硬件检测.jpg
     * 2024-03-06 14:07:03.628  INFO 15144 --- [           main] c.c.c.f.a.i.EdsOssFileUploadServiceImpl  : -------开始只能进入分片上传阶段-------
     * 2024-03-06 14:07:03.918  INFO 15144 --- [           main] c.c.c.f.a.i.EdsOssFileUploadServiceImpl  : 文件分片上传--->196369
     * 2024-03-06 14:07:03.919  INFO 15144 --- [           main] c.c.c.f.a.i.EdsOssFileUploadServiceImpl  : -------所有分片上传完整------->进入分片合并阶段-------
     * 2024-03-06 14:07:03.969  INFO 15144 --- [           main] c.c.c.f.a.i.EdsOssFileUploadServiceImpl  : -------大文件分片上传完成--->196369
     * 2024-03-06 14:07:03.969  INFO 15144 --- [           main] c.c.c.f.FilestoreApplicationTest         : 上传执行时间(ms):699
     * 2024-03-06 14:07:03.969  INFO 15144 --- [           main] c.c.c.f.FilestoreApplicationTest         : 上传成功:1afe99dec706c24e174f5d22e08b48b7-1
     */
    @Test
    void contextLoads() {
        try {
            File fileLocal = new File("D:\\硬件检测.jpg");
            String originalFilename = fileLocal.getName();
            String key = UUID.randomUUID() + "/" + originalFilename;
            logger.info("上传生成的=" + key);
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            CompleteMultipartUploadResult result = edsOssFileUploadService.bigFileListShardingUpload(key, fileLocal);
            stopWatch.stop();
            logger.info("上传执行时间(ms):" + stopWatch.getTotalTimeMillis());
            // 处理上传结果
            String eTag = result.getETag();
            // ...
            logger.info("上传成功:" + eTag);
        } catch (Exception e) {
            logger.error("上传失败", e);
        }
    }

    /**
     * 高级API大文件上传EDS云对象存储测试
     */
    @Test
    void contextLoadsBigFile() {
        try {
            File fileLocal = new File("D:\\fileTemp\\深信服OSS\\aws-java-sdk-1.12.643.zip");
            String originalFilename = fileLocal.getName();
            String key = UUID.randomUUID() + "/" + originalFilename;
            logger.info("上传生成的=" + key);
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            String eTag = edsOssFileUploadService.highLevelMultipartUpload(key, fileLocal);
            stopWatch.stop();
            logger.info("上传执行时间(ms):" + stopWatch.getTotalTimeMillis());
            // ...
            logger.info("上传成功:" + eTag);
        } catch (Exception e) {
            logger.error("上传失败", e);
        }
    }

    /**
     * 分片API大文件上传EDS云对象存储测试
     */
    @Test
    void contextLoadsBigFileShare() {
        try {
            File fileLocal = new File("D:\\fileTemp\\深信服OSS\\aws-java-sdk-1.12.643.zip");
            String originalFilename = fileLocal.getName();
            String key = UUID.randomUUID() + "/" + originalFilename;
            logger.info("上传生成的=" + key);
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            CompleteMultipartUploadResult result = edsOssFileUploadService.uploadLargeFileToS3(new FileInputStream(fileLocal), fileLocal.length(), key);
            stopWatch.stop();
            logger.info("上传执行时间(ms):" + stopWatch.getTotalTimeMillis());
            // 处理上传结果
            String eTag = result.getETag();
            // ...
            logger.info("上传成功:" + eTag);
        } catch (Exception e) {
            logger.error("上传失败", e);
        }
    }

    /**
     * 文件下载
     */
    @Test
    void contextLoadsDownFile() {
        try {

            String key = "26438e0c-e379-4343-b645-03e8056baaf6/硬件检测.jpg";
            logger.info("文件下载的key=" + key);
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            InputStream inputStream = edsOssFileUploadService.downloadToEDS(key);
            stopWatch.stop();
            logger.info("文件下载执行时间(ms):" + stopWatch.getTotalTimeMillis());
            // 处理结果
            if (inputStream != null) {
                // ...
                logger.info("文件下载:");
            }
        } catch (Exception e) {
            logger.error("文件下载", e);
        }
    }

    /**
     * 预签名URL+文件下载: 测试通过
     * 2024-03-06 14:10:26.721  INFO 29356 --- [           main] c.c.c.f.FilestoreApplicationTest         : 文件下载的key=26438e0c-e379-4343-b645-03e8056baaf6/硬件检测.jpg
     * 2024-03-06 14:10:26.763  INFO 29356 --- [           main] c.c.c.f.FilestoreApplicationTest         : 文件下载执行时间(ms):41
     * 2024-03-06 14:10:26.763  INFO 29356 --- [           main] c.c.c.f.FilestoreApplicationTest         : 文件下载:http://10.1.2.16:12001/digtal_resources/26438e0c-e379-4343-b645-03e8056baaf6/%E7%A1%AC%E4%BB%B6%E6%A3%80%E6%B5%8B.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240306T061026Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3599&X-Amz-Credential=MOTNMUS8FJ8P3YTXQSB5%2F20240306%2F%2Fs3%2Faws4_request&X-Amz-Signature=9536999bbc0f1b6de5bb3cf910af0def5ee1f04389446a1688724f27d5655e65
     */
    @Test
    void createSignedUrlForStringGet() {
        try {

            String key = "26438e0c-e379-4343-b645-03e8056baaf6/硬件检测.jpg";
            logger.info("文件下载的key=" + key);
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            URL url = edsOssFileUploadService.createSignedUrlForStringGet("digtal_resources", key);
            stopWatch.stop();
            logger.info("文件下载执行时间(ms):" + stopWatch.getTotalTimeMillis());
            // 处理结果
            if (url != null) {
                // ...
                logger.info("文件下载:" + url);
            }
        } catch (Exception e) {
            logger.error("文件下载", e);
        }
    }

    /**
     * 预签名文件上传
     */
    @Test
    void createSignedUrlForStringPut() {
        try {

            String key = "26438e0c-e379-4343-b645-03e8056baaf6/硬件检测.jpg";
            logger.info("文件上传的key=" + key);
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            URL url = edsOssFileUploadService.createSignedUrlForStringPut("digtal_resources", key);
            stopWatch.stop();
            logger.info("文件上传执行时间(ms):" + stopWatch.getTotalTimeMillis());
            // 处理结果
            if (url != null) {
                // ...
                logger.info("文件上传:" + url);
            }
        } catch (Exception e) {
            logger.error("文件上传", e);
        }
    }
}
写在最后

如果发现上传后,无法访问返回的地址,可以尝试从返回地址下载!!!

@GetMapping("/test1")
	public void contextLoads() {
		try {
			File fileLocal = new File("D:\\a.png");
			String originalFilename = fileLocal.getName();
			String key = UUID.randomUUID() +SEPARATOR + originalFilename;
			logger.info("上传生成的=" + key);
			StopWatch stopWatch = new StopWatch();
			stopWatch.start();
			CompleteMultipartUploadResult result = edsOssFileUploadService.bigFileListShardingUpload(key, fileLocal);
			stopWatch.stop();
			logger.info("上传执行时间(ms):" + stopWatch.getTotalTimeMillis());
			// 处理上传结果
			String eTag = result.getETag();
			// ...
			logger.info("上传成功:" + eTag);
			logger.info(result.getLocation());
		} catch (Exception e) {
			logger.error("上传失败", e);
		}
	}

	@GetMapping("/test2")
	public void createSignedUrlForStringGet2(@RequestParam("key") String key) {
		try {
			logger.info("文件下载的key=" + key);
			StopWatch stopWatch = new StopWatch();
			stopWatch.start();
			InputStream inputStream =null;
			OutputStream outputStream=null;
			try{
				inputStream=edsOssFileUploadService.downloadToEDS(key, "bucket01-test");
				stopWatch.stop();
				logger.info("文件下载执行时间(ms):" + stopWatch.getTotalTimeMillis());
				outputStream = new FileOutputStream("D:\\985.png");
				byte[] buffer = new byte[1024];
				int bytesRead;
				while ((bytesRead = inputStream.read(buffer)) != -1) {
					outputStream.write(buffer, 0, bytesRead);
				}
			}catch (Exception e){
				logger.error("下载文件失败", e);
			}finally {
				if (outputStream!=null){
					outputStream.close();
				}
				if (inputStream!=null){
					inputStream.close();
				}
			}


		} catch (Exception e) {
			logger.error("文件下载", e);
		}
	}

Spring Boot项目集成AWS SDK,可以实现与AWS S3的连接并实现文件的上传和下载功能。 首先,需要在pom.xml文件中添加AWS SDK的依赖项,并确保version保持一致。在dependencyManagement中添加以下代码: ``` <dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.0.0-preview-12</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` 然后,在dependencies中添加以下代码: ``` <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <version>2.0.0-preview-12</version> </dependency> ``` 接下来,在application.properties文件中进行配置,包括AWS的访问密钥、S3存储桶名称、存储桶所在地区以及上传文件的路径: ``` aws.access_key_id=your access key aws.secret_access_key=your secret access key aws.s3.bucket=your bucket name aws.s3.region=cn-northwest-1 aws.s3.filename=/666666/test123/photo.zip ``` 在文件上传和下载的方法中,需要注意传递给方法的key参数是指存储在AWS S3上的文件名。如果key参数是路径字符串格式,S3服务器会自动创建对应路径的文件夹。例如,如果在application.properties中设置了aws.s3.filename=/666666/test123/photo.zip,那么key参数为/666666/test123/photo.zip,S3存储桶下就会有一个名为/666666/test123/photo.zip的文件,即上传的文件。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Spring Boot项目集成AWS SDK连接到AWS S3,实现上传下载功能](https://blog.csdn.net/sinat_27428951/article/details/89675587)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值