本文使用alioss 及 个人搭建的 minioOss进行演示

在SpringBoot中使用Oss进行文件上传下载, 首先要配置oss的 endPoint, accessKeyId, accessKeySecret及bucketName

一 在pom文件里引入 aliOss或 minioOss的maven地址

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- aliOss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun.sdk.oss}</version>
</dependency>

<!-- minioOss -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio}</version>
</dependency>

二 在配置文件中加入从Oss网站获取的必要数据

``application.ym

1
2
3
4
5
6
7
8
9
10
alioss:
endpoint: ${work.alioss.endpoint}
accessKeyId: ${work.alioss.accessKeyId}
accessKeySecret: ${work.alioss.accessKeySecret}
bucketName: ${work.alioss.bucket-name}
minio:
endpoint: ${work.minio.endpoint}
accessKeyId: ${work.minio.accessKeyId}
accessKeySecret: ${work.minio.accessKeySecret}
bucketName: ${work.minio.bucket-name}

三 为这些数据创建 properties类, 通过配置文件注解赋值

``AliOssPropertis.java

1
2
3
4
5
6
7
8
9
10
11
@Component
@ConfigurationProperties(prefix = "work.alioss")
@Data
public class AliOssProperties {

private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;

}

``MinioProperties.java

1
2
3
4
5
6
7
8
9
@Component
@ConfigurationProperties(prefix = "work.minio")
@Data
public class MinioProperties {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
}

四 为Oss文件上传创建工具类, 便于调用

``AliOssUtil.java

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
@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;

/**
* 文件上传
*
* @param bytes
* @param objectName
* @return
*/
public String upload(byte[] bytes, String objectName) {

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

try {
// 创建PutObject请求。
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
} 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();
}
}

//文件访问路径规则 https://BucketName.Endpoint/ObjectName
StringBuilder stringBuilder = new StringBuilder("https://");
stringBuilder
.append(bucketName)
.append(".")
.append(endpoint)
.append("/")
.append(objectName);

log.info("文件上传到:{}", stringBuilder.toString());

return stringBuilder.toString();
}
}

``MinioUtil.java

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
@Data
@AllArgsConstructor
@Slf4j
public class MinioUtil {

private String endpoint;
private String accessKey;
private String secretKey;
private String bucketName;

public String upload(MultipartFile file, String objectName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, io.minio.errors.ServerException {
// 实例化客户端
MinioClient client = MinioClient.builder()
.endpoint(this.endpoint)
.credentials(this.accessKey, this.secretKey)
.build();

InputStream inputStream = null;
try {
inputStream = file.getInputStream();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
client.putObject(PutObjectArgs.builder()
.bucket(this.bucketName)
.object(objectName)
.stream(inputStream, file.getSize(), -1)
.contentType(file.getContentType())
.build());

return this.endpoint + "/" + this.bucketName + "/" + objectName;
}

}

五 在配置类中将 propertis配置文件的数据赋值给 OssUtil工具类, 并通过 @Bean注解加入Spring容器

``OssConfiguration.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
@Slf4j
public class OssConfiguration {

@Bean
@ConditionalOnMissingBean
public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties) {
log.info("开始创建阿里云文件上传文件工具类对象: {}", aliOssProperties);
return new AliOssUtil(aliOssProperties.getEndpoint(),
aliOssProperties.getAccessKeyId(),
aliOssProperties.getAccessKeySecret(),
aliOssProperties.getBucketName());
}

@Bean
@ConditionalOnMissingBean
public MinioUtil minioUtil(MinioProperties minioProperties) {
log.info("开始创建Minion文件上传文件工具类对象: {}", minioProperties);
return new MinioUtil(minioProperties.getEndpoint(),
minioProperties.getAccessKeyId(),
minioProperties.getAccessKeySecret(),
minioProperties.getBucketName());
}
}

六 创建 CommonController控制类, 将 Oss文件上传下载具象化, 便于前端调用

``CommonController

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
@RestController
@RequestMapping("/admin/common")
@Api(tags = "通用接口")
@Slf4j
public class CommonController {

@Autowired
private AliOssUtil aliOssUtil;

@Autowired
private MinioUtil minioUtil;

/**
* 文件上传
* @param file
* @return
*/
@PostMapping("/upload")
@ApiOperation("文件上传")
public Result<String> upload(@RequestParam("file") MultipartFile multipartFile) {
log.info("文件上传: {}", multipartFile);

try {
// 获取原始文件名
String originalFilename = multipartFile.getOriginalFilename();
// 截取原始文件名后缀
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
// 构建新文件名称
String fileName = UUID.randomUUID() + extension;
// 文件的请求路径
String filePath = aliOssUtil.upload(multipartFile.getBytes(), fileName);
return Result.success(filePath);
} catch (IOException e) {
log.error("文件上传失败: {}", e.getMessage());
}
return Result.error(MessageConstant.UPLOAD_FAILED);
}

/**
* 文件上传
* @param file
* @return
*/
@PostMapping("/upload")
@ApiOperation("文件上传接口")
public Result<String> uploadMin(@RequestParam("file") MultipartFile file) {
log.info("文件上传 : {}", file);
String originalFilename = file.getOriginalFilename();
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
String objectName = UUID.randomUUID() + extension;
String filePath = null;
try {
filePath = minioUtil.upload(file, objectName);
return Result.success(filePath);
} catch (Exception e) {
log.error("文件上传失败: {}", e);
return Result.error(MessageConstant.UPLOAD_FAILED);
}
}
}

七 此时可以通过调用 localhost/admin/common/upload 上传文件, 上传成功会返回filePath, 可以通过filePath访问上传的文件