Spring Boot项目集成AWS S3,实现上传下载功能
AWS S3介绍
下面因为使用到的功能很简单,下面会贴出S3的官网链接,有兴趣的同学可以去自行了解详情
AWS S3(官网): https://www.amazonaws.cn/s3/
AWS SDK for Java(官网): https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/signup-create-iam-user.html
加入相关的pom文件依赖
不同版本的SDK官网描述会有冲突,暂未遇到相关问题,附上pom依赖版本信息, 只是使用了S3的简单功能,实现文件的上传/下载
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 Java S3-->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.11.821</version>
</dependency>
编码思路
S3作为文件存储服务器,想要与S3交互,类似以阿里云的OSS文件存储服务器,有一个简单的客户端去挑起文件上传,调用S3封装的文件上传API实现文件的上传下载
configClient
springboot配置项目 , 此处不做过多赘述.yaml文件配置
s3:
service.end.point: localhost:8080
accessKey: accessKey
secretKey: secretKey
bucket.name: /filePath
Amazon S3 配置
@Value("${biz.s3.service.end.point}")
public String endPoint;
@Value("${biz.s3.accessKey}")
public String accessKey;
@Value("${biz.s3.secretKey}")
public String secretKey;
/**
* 初始化生成AmazonS3 客户端配置
* @return
*/
@Bean
public AmazonS3 s3client() {
log.info("start create s3Client");
AwsClientBuilder.EndpointConfiguration endpointConfig =
new AwsClientBuilder.EndpointConfiguration(endPoint, Region.getRegion(Regions.CN_NORTH_1).getName());
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey,secretKey);
AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol(Protocol.HTTP);
AmazonS3 S3client = AmazonS3Client.builder()
.withEndpointConfiguration(endpointConfig)
.withClientConfiguration(clientConfig)
.withCredentials(awsCredentialsProvider)
.disableChunkedEncoding()
.withPathStyleAccessEnabled(true)
.withForceGlobalBucketAccessEnabled(true)
.build();
log.info("create s3Client success");
return S3client;
}
注意此处有一个比较坑的地方 clientConfig.setProtocol(Protocol.HTTP): 一定要配置S3的客户端的链接协议,如果未配置此项,会出现上传错误问题,此项的配置用于指定向S3服务器发起的请求方式(http/https) , 初次使用的小伙伴很容易踩坑 ,下面附上错误信息,小伙伴可以根据具体的需要去配置不同的传输协议,还可以配置存活/异常链接等等
com.amazonaws.SdkClientException: Unable to execute HTTP request: Unsupported or unrecognized SSL message
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleRetryableException(AmazonHttpClient.java:1207)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1153)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttmeworkServlet.processRequest(FrameworkServlet.java:1005)
Caused by: javax.net.ssl.SSLException: Unsupported or unrecognized SSL message
at java.base/sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(SSLSocketInputRecord.java:439)
at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:184)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:108)
上传java实现
此处有一个需要注意的细节.withCannedAcl(CannedAccessControlList.PublicRead)) 配置文件的访问路径,因为我这里想直接通过url访问,又不想写在给文件下载再去提供一个接口, 拼接对应的文件路径,实测可用
@Value("${biz.s3.bucket.name}")
public String bucketName;
@Value("${biz.s3.service.end.point}")
public String endPoint;
@PostMapping(value = "/testList")
public Result test(@RequestParam(required = true) MultipartFile file){
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(file.getContentType());
objectMetadata.setContentLength(file.getSize());
try {
String key = System.currentTimeMillis() + file.getOriginalFilename();
PutObjectResult result = amazonS3.putObject(new PutObjectRequest(bucketName, key , file.getInputStream(), objectMetadata)
.withCannedAcl(CannedAccessControlList.PublicRead)); //配置文件访问权限
//文件访问路径
String url = endPoint + bucketName + "/" + key;
System.out.println(url);
} catch (Exception e) {
e.printStackTrace();
}
return Result.success();
}
内联此处还有一种方式可以获取文件的访问路径,调用此方法的优点在于,直接拿到key 用户需要下载,可以动态配置访问文件的时间,提高系统的安全性,推荐使用此种方式
/**
* 获取文件下载路径
* @param key 文件的key
* @return
*/
private static String downloadFile(String key){
try {
if(StringUtils.isEmpty(key)){
return null;
}
GeneratePresignedUrlRequest httpRequest = new GeneratePresignedUrlRequest(BUCKET_NAME, key);
return s3.generatePresignedUrl(httpRequest).toString();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
至此,简单的上传/下载文件至S3已经完成
上一篇: PHP延迟静态绑定
下一篇: coreseek 支持sqlite