阿里云OSS对象存储

1. OOS 简介

‌阿里云OSS(Object Storage Service)是一种基于云存储的产品,适用于存储和管理各种类型的文件,包括图片、视频、文档等。‌ 阿里云OSS具有高可靠性、高可用性和低成本等优点,因此被广泛应用于各种场景,包括作为图片服务器‌。

阿里云OSS图片服务提供了多种功能,包括图片信息获取、格式转换、缩放、裁剪、旋转等。用户可以通过简单的RESTful接口在任何时间、任何地点对图片进行处理。此外,阿里云OSS还支持通过URL形式进行图片处理,用户可以通过URL中的QueryString指定处理参数,直接访问处理后的图片,这种方式简单方便,无需编写额外的代码‌。

1.2. 购买

image-20250526222603429

购买完成后进入OSS创建桶管理

image-20250526223057641

image-20250526223417554

创建一个Key对外访问

1.3 帮助文档

ali - OSS官方文档OSS Java SDK兼容性和示例代码_对象存储(OSS)-阿里云帮助中心 (aliyun.com)

image-20250526224211127

1
2
3
4
5
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.4</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>

复制这里的外网访问端口和存储空间名称

image-20250526224432693

2.项目编写

2.1 Return返回类

使用json格式返回一样的效果

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
package com.kdd.oss.common;

public class Return<T> {
private String message;
private T data;
private boolean success;

public Return(String message, T data, boolean success) {
this.message = message;
this.data = data;
this.success = success;
}

// Getters and Setters
public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public T getData() {
return data;
}

public void setData(T data) {
this.data = data;
}

public boolean isSuccess() {
return success;
}

public void setSuccess(boolean success) {
this.success = success;
}
}

2.2 异常处理类

全局的异常返回输出,更好的调试项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.kdd.oss.common;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(Exception.class)
public ResponseEntity<Return<String>> handleException(Exception e) {
Return<String> response = new Return<>("Error: " + e.getMessage(), null, false);
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

2.3 service服务层

1
2
3
4
5
6
7
8
package com.kdd.oss.service;

import java.io.InputStream;

public interface OssService {
String uploadFile(String fileName, InputStream inputStream);
void deleteFile(String fileName);
}

2.4 serviceImpl

参考项目文档可以知道,上传文件就是构造ossClient将Key和文件流一起传输过去,删除就更简单了,直接传输需要删除的文件名字就行。

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
package com.kdd.oss.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.kdd.oss.service.OssService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.InputStream;

@Service
public class OssServiceImpl implements OssService {

@Value("${aliyun.oss.endpoint}")
private String endpoint;

@Value("${aliyun.oss.access-key-id}")
private String accessKeyId;

@Value("${aliyun.oss.access-key-secret}")
private String accessKeySecret;

@Value("${aliyun.oss.bucket-name}")
private String bucketName;

@Override
public String uploadFile(String fileName, InputStream inputStream) {
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
ossClient.putObject(new PutObjectRequest(bucketName, fileName, inputStream));
return "https://" + bucketName + "." + endpoint + "/" + fileName;
} finally {
ossClient.shutdown();
}
}

@Override
public void deleteFile(String fileName) {
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
ossClient.deleteObject(bucketName, fileName);
} finally {
ossClient.shutdown();
}
}
}

2.5 接口控制层

通过接口使得外部进行数据传输

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
package com.kdd.oss.controller;

import com.kdd.oss.common.Return;
import com.kdd.oss.service.OssService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@RestController
@RequestMapping("/images")
public class ImageController {

private final OssService ossService;

@Autowired
public ImageController(OssService ossService) {
this.ossService = ossService;
}

@PostMapping("/upload")
public Return<String> uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
String imageUrl = ossService.uploadFile(file.getOriginalFilename(), file.getInputStream());
return new Return<>("Upload success", imageUrl, true);
}

@DeleteMapping("/delete/{fileName}")
public Return<String> deleteImage(@PathVariable String fileName) {
ossService.deleteFile(fileName);
return new Return<>("File deleted successfully: " + fileName, null, true);
}
}

2.6 yml配置

image-20250527225340911

3. 项目测试

image-20250527225448790

image-20250527225515430

文件成功上传!!!

image-20250527225604631

文件删除成功

4. 上传与回显

使用jquery异步传输,jquery.min.js可以使用网络地址也可以下载加快访问

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
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片上传</title>
<script src="jquery.min.js"></script>
<style>
#input_img {
width: 300px;
height: 300px;
border: 1px solid #ccc;
object-fit: cover;
}
</style>
</head>
<body>
<div class="modal-body">
<form id="uploadForm" method="post" enctype="multipart/form-data">
<input type="file" name="file" id="img" style="display: none;" accept="image/*">
<label for="img" style="cursor: pointer;">
<img id="input_img" src="img/upimg.png" alt="点击上传">
</label>
</form>
</div>

<script>
$(document).ready(function () {
// 绑定文件输入框的变化事件
$("#img").change(uploadFile);
});

function uploadFile() {
var myform = new FormData(document.getElementById("uploadForm"));
var file = $("#img")[0].files[0];

if (!file) {
alert("请选择文件");
return;
}

$.ajax({
url: "/images/upload", // 调整为控制器的 URL
type: "POST",
data: myform,
contentType: false,
processData: false,
success: function (result) {
console.log(result);
alert("上传成功!");
// 假设返回的结构中包含图片 URL
$("#input_img").attr("src", result.data); // 更新显示的图片路径
},
error: function () {
alert("系统错误");
}
});
}
</script>
</body>
</html>
1
官网jquery压缩版引用地址:

 3.1.1版本:

  

3.0.0版本:

  

 2.1.4版本:

  

image-20250527230008450

image-20250527230101643

5. 进阶

5.1 修改上传路径

直接在上传的url中指定拼接即可,修改业务逻辑代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
public String uploadFile(String fileName, InputStream inputStream) {
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
String targetDirectory = "market/user/";
// 确保目录路径以斜杠结尾
if (!targetDirectory.endsWith("/")) {
targetDirectory += "/";
}
String objectKey = targetDirectory + fileName;
try {
ossClient.putObject(new PutObjectRequest(bucketName, objectKey, inputStream));
return "https://" + bucketName + "." + endpoint + "/" + objectKey;
} finally {
ossClient.shutdown();
}
}

5.2 生成uuid

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
@Override
public String uploadFile(String originalFileName, InputStream inputStream) {
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
String targetDirectory = "market/user/";
// 确保目录路径以斜杠结尾
if (!targetDirectory.endsWith("/")) {
targetDirectory += "/";
}
// 生成UUID文件名
String fileExtension = getFileExtension(originalFileName);
String uuidFileName = UUID.randomUUID().toString() + fileExtension;
String objectKey = targetDirectory + uuidFileName;
try {
ossClient.putObject(new PutObjectRequest(bucketName, objectKey, inputStream));
return "https://" + bucketName + "." + endpoint + "/" + objectKey;
} finally {
ossClient.shutdown();
}
}

private String getFileExtension(String fileName) {
int lastIndexOf = fileName.lastIndexOf(".");
if (lastIndexOf == -1) {
return ""; // 无扩展名
}
return fileName.substring(lastIndexOf);
}