图片上传至阿里云OSS

Springboot项目中实现图片上传至阿里云OSS的功能的实现过程

1.开通阿里云对象存储OSS

2.创建Bucket

创建完成后在 文件管理-文件列表 中可以管理文件

概览中可以查看访问端口

3.导入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.7.0</version>
</dependency>

4.编写工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.zgl.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import java.util.UUID;

public class OssUpload {
/**
* //需要的参数
* //Bucket域名
* //Endpoint(地域节点)
* //AccessKeyId
* //AccessKey Secret
* //Bucket的名字
*/
public static final String ali_domain = "Bucket域名";
public static final String endpoint = "Endpoint(地域节点)";
public static final String accessKeyId = "AccessKeyId";
public static final String accessKeySecret = "AccessKey Secret";
public static final String bucketName = "buckerName";

//静态方法
public static String uploadImg(MultipartFile file){
try {
//1.生成文件名
String originalFilename = file.getOriginalFilename();
String extension = "."+FilenameUtils.getExtension(originalFilename);
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
String fileName = uuid+extension;
//2.创建OSS客户端对象
OSS ossClient = new OSSClientBuilder().build(
endpoint,
accessKeyId,
accessKeySecret);
//3.设置请求头
ObjectMetadata meta = new ObjectMetadata();
meta.setContentType("image/jpg");
//4.执行操作
ossClient.putObject(
bucketName,
fileName,
file.getInputStream(),
meta
);
ossClient.shutdown();
//5.返回访问地址
return ali_domain + fileName;

}catch(Exception e) {
e.printStackTrace();
return null;
}
}

}

参数在阿里云的OSS管理控制台可以看到

其中AccessKeyIdAccessKey Secret可以在图片中的页面中得到

5.测试

Controller接口

1
2
3
4
5
6
7
@RestController
public class TestController {
@PostMapping("/upload")
public String upload(MultipartFile file){
return OssUpload.uploadImg(file);
}
}

前端页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" value="上传图片">
<input type="submit" value="上传">
</form>

</body>
</html>

看到页面返回了图片的url,再到阿里云的控制台可以看到已经上传成功了

6.补充

规范化

原本是直接把配置信息写在类中,并直接调用工具类的静态方法。

1
2
3
4
5
6
7
/*	
public static final String ali_domain = "Bucket域名";
public static final String endpoint = "Endpoint(地域节点)";
public static final String accessKeyId = "AccessKeyId";
public static final String accessKeySecret = "AccessKey Secret";
public static final String bucketName = "buckerName";
*/

规范化的写法应该是

  1. 配置信息写在 application-dev.yaml 中,而 application.yaml 引用dev中的配置

    比如下面这个项目中的写法

    application-dev.yaml中写配置信息,而在application.yaml中引用即可

  2. 然后用一个配置属性类封装配置信息

  3. 将工具类中的方法不使用静态,而是通过配置类,将工具类交给IOC容器管理

  4. 通过@Autowired注入工具类对象,调用方法

新版补充

文档中心:各语言SDK参考文档_对象存储 OSS-阿里云帮助中心 (aliyun.com)

新版的OSS在OSS_ACCESS_KEY_IDOSS_ACCESS_KEY_SECRET的操作上有改动,需要将它们加入到本地电脑的系统变量中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
public class AliOssUtil {

public static void upload(MultipartFile multipartFile) throws Exception {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 从环境变量中获取访问凭证。运行本代码示例之前
//请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider =
CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填写Bucket名称,例如examplebucket。
String bucketName = "sky-take-out-bucket-zgl";
// 填写Object完整路径,完整路径中不能包含Bucket名称
// 例如exampledir/exampleobject.txt。
String objectName = "test.png";


// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder()
.build(endpoint, credentialsProvider);

try {
// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest(
bucketName, objectName,
multipartFile.getInputStream());
// 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS,
// StorageClass.Standard.toString());
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);

// 上传文件。
PutObjectResult result = ossClient.putObject(putObjectRequest);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, "+
"which means your request made it to OSS"+
"but was rejected with an error response"+
" for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, "+
"which means the client encountered "
+ "a serious internal problem while "+
"trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
1
2
3
4
5
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>