当前位置: 首页 > news >正文

AWS S3 SDK FOR JAVA 基本使用及如何兼容七牛云

为什么写这篇文章

项目里面使用到了七牛云,原来是基于七牛云的SDK来实现,后面由于内网部署的问题,考虑换成Minio,此时面临一个问题,需要修改代码。如果后期要换成阿里的SSO呢?或者换成腾讯云呢?那每次都要修改代码太麻烦,而且最主要的是我的需求可能是在内网环境我使用Minio,而在外网环境我又要使用七牛云。有没有一种办法是不需要修改代码只修改一些配置文件就能切换多个云平台呢?找了一下,AWS的S3应该是满足的。

我理解的AWS S3

S3是亚马逊平台的文件管理协议,猜测是因为用的人多且推出较早,后期推出的很多云存储都对S3协议有支持,比如七牛云的支持连接:https://developer.qiniu.com/kodo/4086/aws-s3-compatible
在这里插入图片描述
其他的阿里云,腾讯云,Minio据说也是支持的

如何使用(基于Springboot项目)

1、导入maven包

<dependency><groupId>com.amazonaws</groupId><artifactId>aws-java-sdk-s3</artifactId><version>1.12.540</version>
</dependency>

2、增加yml相关配置

s3:accessKey: xxxsecretKey: xxxbucketName: xxendpoint: https://s3.cn-south-1.qiniucs.comregion: cn-south-1

3、S3ClientConfig

package com.yrt.framework.config;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.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author :GuangXiZhong* @date :Created in 2025/6/10 15:21* @description:*/
@Configuration
public class S3ClientConfig {@Value("${s3.accessKey}")private String accessKey;@Value("${s3.secretKey}")private String secretKey;@Value("${s3.endpoint}")private String endpoint;@Value("${s3.region}")private String region;@Beanpublic AmazonS3 amazonS3Client() {// 初始化 S3 客户端AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, region);BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);return AmazonS3ClientBuilder.standard().withEndpointConfiguration(endpointConfiguration).withCredentials(new AWSStaticCredentialsProvider(awsCreds)).build();}
}

4、S3Service上传服务

package com.yrt.common.utils;import com.amazonaws.HttpMethod;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;@Service
public class S3Service {@Value("${s3.bucketName}")private String bucketName;@Autowiredprivate AmazonS3 s3Client;// 上传文件public String uploadFile(String key, File file) {s3Client.putObject(new PutObjectRequest(bucketName, key, file));return s3Client.getUrl(bucketName, key).toString();}// 上传文件并指定文件名public String uploadFileWithKey(String key, InputStream inputStream) throws IOException {ObjectMetadata metadata = new ObjectMetadata();metadata.setContentLength(inputStream.available());s3Client.putObject(new PutObjectRequest(bucketName, key, inputStream, metadata));return s3Client.getUrl(bucketName, key).toString();}// 删除文件public void deleteFile(String key) {s3Client.deleteObject(new DeleteObjectRequest(bucketName, key));}// 获取文件的公共访问链接public String getFilePublicUrl(String key) {return s3Client.getUrl(bucketName, key).toString();}// 获取文件的私有访问链接(带签名)public String getFileSignedUrl(String key, long expirationTime) {Date expirationDate = new Date(System.currentTimeMillis() + expirationTime);GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key).withMethod(HttpMethod.GET).withExpiration(expirationDate);URL signedUrl = s3Client.generatePresignedUrl(request);return signedUrl.toString();}
}

5、测试

package com.yrt;import com.yrt.common.utils.S3Service;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;import java.io.File;/*** @author :GuangXiZhong* @date :Created in 2025/4/23 16:06* @description:*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("dev")
public class S3Test {@Autowiredprivate S3Service s3Service;/*** S3测试*/@org.junit.Testpublic void testS3() {File file = new File("/Users/zhongguangxi/Documents/测试图片.png");System.out.println(s3Service.uploadFile("test2561018", file));}
}

运行一下可以看到输出了URL,说明成功了,此时去七牛空间看一下也能看到确实上传上去了
在这里插入图片描述

在这里插入图片描述

题外话:关于如何设置SDK的代理

有时候系统需要在内网服务器部署,内网服务器本身不通外网,但可以通过前置机服务器访问外网,需要再前置机上放置一个nginx代理,然后把sdk的上传地址设置成前置机的地址,通过nginx代理出去外网,但是此时遇到了一个问题

SDK的连接地址是直接写死在源码里面的,怎么修改这个地址呢?

我咨询了七牛云的工程师,给到的回复是

Java SDK本身并不直接提供设置代理的功能,你可以通过配置底层的HTTP客户端来实现代理设置,在七牛的Java SDK中,通常使用的是OkHttp作为默认的HTTP客户端。要设置代理,你需要自定义OkHttpClient实例,并在其中配置代理参数。

为此我尝试了如下办法

System.setProperty("http.proxyHost", "前置机IP");
System.setProperty("http.proxyPort", "代理端口");System.setProperty("https.proxyHost", "前置机IP"); 
System.setProperty("https.proxyPort", "代理端口");

相关文章:

  • 云计算——弹性云服务器(ECS)和裸金属服务器(BMS)
  • 小程序中的状态管理库-mobx-miniprogram
  • CentOS下的运维监控Grafana部署
  • 云计算——弹性云计算器(ECS)
  • 小程序动画性能提升指南:CSS硬件加速与JavaScript动画框架对比
  • Docker 运行 Kafka 带 SASL 认证教程
  • CARSIM-车速、油门、刹车练习
  • 破界协同:解锁电商平台混合云架构的双引擎效能
  • 微信小程序之bind和catch
  • Qt5 框架 CMake 探秘
  • C++11 花括号等式初始化器(Brace-or-Equal Initializers):从入门到精通
  • 顺应智能化建筑趋势,IBMS管理平台应用前景无限延伸
  • DMA:在不同内存空间建立目的地址的情况分析及后果
  • 服务器内存能不能用在台式机上
  • 网格布局示例代码解析
  • VSCode中PHP使用Xdebug
  • Easy系列PLC变频器控制功能块(ST源代码)
  • VsCode 离线插件下载
  • (1-6-5)Java 多线程(定长线程池)下载器(案例)
  • React 中的TypeScript开发范式
  • 上海响应式网站制作公司/seo网站营销公司哪家好
  • VPS做镜像网站/在线看seo网站
  • 网站开发怎么写/百度搜索关键词规则
  • 网站充值怎么做分录/软文代写接单平台
  • 用前端做的比较酷的网站/重庆网站排名优化教程
  • 开源镜像网站怎么做/湘潭网页设计