记忆备注 📝 :
bucket
是一个单独的仓库,仓库内无论目录 还是其他资源 统一都视为资源,定位和存储资源的方式,就是要将资源在bucket
中的相对位置描述清楚。SDK 中很多的 API 参数都是
(String bucketName,String path)
的形式,根据上述的记忆备注,也就很好理解了。
1. 依赖
注意版本,以 Maven 仓库或者最新的官方文档为主
xml
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
2. 前期准备
- accessKeyId
- secretAccessKey
- 创建一个 bucket
3. 任务学习
3.1 接口
Controller 简易接口。注意
bucketName
和path
需要定义清楚,这里的 path 传入表示的是目录。OSSUtils
是一个工具类,在 4.2 将讲述。
- 上传的接口
java
@PostMapping("/uploadFile")
public Boolean uploadFile(@RequestParam("file") MultipartFile file) {
// check
try {
boolean upload = OSSUtils.upload(bucketName, path, file);
return upload;
}catch (Exception e) {
// 打印日志
return false;
}
}
- 查看和下载的接口
使用了统一的返回体
java
public WebResultVO<JSONArray> getClusterRsList() {
try {
JSONArray arr = OSSUtils.list(bucketName, path);
return WebResultVO.success(arr);
} catch (Exception e) {
return WebResultVO.failure(e.getMessage());
}
}
3.2 工具类
提供两个方法:上传 和 列表(包括下载链接)
- 客户端
创建客户端的目的就是为了使用其 API 操作 OSS 服务器。原则是执行一个操作时生成一个cliet,操作执行完毕后关闭client。
该静态方法可以写在工具类中,每次调用生成一个新的 client
java
public static OSS buildOssClient() {
return new OSSClientBuilder().build("endpoint", "accessKeyId", "secretAccessKey");
}
- 上传
上传涉及到文件的名称以及后缀的处理,本文使用的是 Spring 提供的 MultipartFile
,它提供了 API 帮助我们完成文件名的操作。
以 abc.txt
为例子:
java
String fileName = file.getOriginalFilename(); // abc.txt
String baseName = FileNameUtil.getBaseName(fileName); // abc
String extension = FileNameUtil.getExtension(fileName); // txt
这里用到了一个依赖:jodd
。
java
public static boolean upload(String bucketName, String path, MultipartFile file) throws Exception {
// 获取到 client
OSS ossClient = OSSUtils.buildOssClient();
try {
InputStream is = file.getInputStream();
String fileName = file.getOriginalFilename();
String baseName = FileNameUtil.getBaseName(fileName);
String extension = FileNameUtil.getExtension(fileName);
ossClient.putObject(bucketName, path + "/" + baseName + "." + extension, is);
return true;
} catch (Exception e) {
throw new Exception("上传文件失败");
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
第 9
行,如果目录未定义的话会报错,因为会使 /
开头,这样是不被允许的。如果想直接存放在 bucket
中,第二个参数,直接写文件名即可。
- 列表
使用 FastJson 提供的
JSONArray
,最终的返回结果长这样。
json
{
"code": "10000",
"msg": "接口请求成功",
"entity": [
{
"fileName": "11.30_XXX.xlsx",
"fileUrl": "http://XXX"
},
{
"fileName": "11.30_XXX.xlsx",
"fileUrl": "http://XXX"
}
],
"success": true
}
这里直接上代码了
java
public static JSONArray list(String bucketName, String path) throws ResultException {
// 列举文件。
OSS ossClient = OSSUtils.buildOssClient();
try {
// 前缀是 path
ObjectListing objectListing = ossClient.listObjects(bucketName, path);
List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
if (ObjectUtils.isEmpty(sums)) {
return new JSONArray();
}
JSONArray arr = new JSONArray();
for (OSSObjectSummary s : sums) {
if (s.getSize() <= 0) {
// 避免目录
continue;
}
//key的格式是 /path/fileName.后缀
String key = s.getKey();
// TODO 提取文件名
obj.put("fileName", fileName);
obj.put("fileUrl", getUrl(bucketName, key));
arr.add(obj);
}
return arr;
} catch (Exception e) {
throw new Exception("获取文件列表失败");
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
这里省略了一些代码,核心思想在第6
行,这里是遍历bucket
中前缀是path
的内容,会把目录和完整文件路径前包含path
的都检索到。
获取可下载的资源路径也比较简单,直接用下面的代码就行,这里的path
是资源的完整路径。
java
private static String getUrl(String bucketName,String path){
OSS ossClient = buildOssClient();
// 设置URL过期时间为1小时
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
GeneratePresignedUrlRequest generatePresignedUrlRequest ;
generatePresignedUrlRequest =new GeneratePresignedUrlRequest(bucketName, path);
generatePresignedUrlRequest.setExpiration(expiration);
URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
return url.toString();
}