前段时间接触到公司使用了Amazon S3协议的文件管理系统,以前从来没接触过Amazon的东西,文档大部分是英文机翻,极不友好。凭借着自己蹩脚的英语水平,跌跌撞撞摸索明白了一些。百度上有一些大佬分享了自己的博客是关于Amazon S3文件上传系统的小工具,但是他们的SDK版本是V1的,和我们的不匹配,无法使用。
官方有一些示例demo可以看,但是路径比较难找,分享一下链接https://docs.aws.amazon.com/zh_cn/code-samples/latest/catalog/code-catalog-javav2-example_code-s3.html
此处只展示Amazon S3需要的两个依赖,其余的Spring依赖根据自己需要再导入
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>example</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.16.60</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
详细的设置看注释
package com.utils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3Configuration;
import software.amazon.awssdk.services.s3.model.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
@Component
public class S3Util {
private static String uri;
private static String bucket;
// application.yml 配置文件的配置
@Value("${s3.uri}")
public static void setUri(String uri) {
S3Util.uri = uri;
}
// application.yml 配置文件的配置
@Value("${s3.bucket}")
public static void setBucket(String bucket) {
S3Util.bucket = bucket;
}
public static S3Client init() throws URISyntaxException {
Region region = Region.US_EAST_1;
S3Configuration s3Config = S3Configuration.builder().pathStyleAccessEnabled(true).build();
URI uriObj = new URI(uri);
S3Client s3 = S3Client.builder().serviceConfiguration(s3Config).region(region).endpointOverride(uriObj).build();
return s3;
}
public static String putS3Object (S3Client s3, String fileName, MultipartFile file, String contentType) {
String strs[] = fileName.split("\\.");
String keyName = strs[0] + System.currentTimeMillis() + "." + strs[1];
try {
PutObjectRequest putOb = PutObjectRequest.builder().bucket(bucket).key(keyName).contentType(contentType).build();
s3.putObject(putOb, RequestBody.fromBytes(file.getBytes()));
return "/" + bucket + "/" + keyName;
} catch (S3Exception | IOException e) {
System.err.println(e.getMessage());
}
return "";
}
public static void getURL(S3Client s3, String keyName) {
try {
GetUrlRequest request = GetUrlRequest.builder().bucket(bucket).key(keyName).build();
URL url = s3.utilities().getUrl(request);
System.out.println("The URL for " + keyName + " is" + url);
} catch (S3Exception e) {
System.err.println(e.awsErrorDetails().errorMessage());
}
}
public static void deleteBucketObjects(S3Client s3, String objectName) {
ArrayList<ObjectIdentifier> toDelete = new ArrayList<>();
toDelete.add(ObjectIdentifier.builder().key(objectName).build());
try {
DeleteObjectsRequest dor = DeleteObjectsRequest.builder().bucket(bucket).delete(Delete.builder().objects(toDelete).build()).build();
s3.deleteObjects(dor);
} catch (S3Exception e) {
System.err.println(e.awsErrorDetails().errorMessage());
}
System.out.println("Done!");
}
}
S3Client s3 = S3Util.init();
String path = S3Util.putS3Object(s3, fileName, file, contentType);
s3.close();
可能有些同学很不理解,这个contentType为什么要自己去设置,默认的不行吗?还真不行,默认的contentType为文件形式,会触发浏览器的下载事件,但是一般会使用S3协议的需求,都是希望能通过链接直接能打开图片、或者视频,无需其它的操作。
如果你不知道这个该怎么设置,可以参看一下开源中国的在线工具。
要配置的东西不多,基本上拿来即用。工具也很简陋,也有升级的空间。参看这个可能未能满足你心中的那种完美工具的标杆,但也能给你一点思路去摸索。