java springboot oss 分片上传 进度条 全代码
时间: 2023-09-19 13:05:19 浏览: 170
以下是Java SpringBoot框架下实现OSS文件分片上传和进度条展示的示例代码:
1. 首先在pom.xml文件中引入OSS SDK依赖:
```xml
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.9.2</version>
</dependency>
```
2. 创建一个名为OSSUtil的工具类,用于连接OSS服务并实现分片上传和进度查询:
```java
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
@Component
public class OSSUtil {
// 阿里云OSS服务的Endpoint
private static final String ENDPOINT = "your_endpoint";
// 阿里云OSS服务的AccessKeyId
private static final String ACCESS_KEY_ID = "your_access_key_id";
// 阿里云OSS服务的AccessKeySecret
private static final String ACCESS_KEY_SECRET = "your_access_key_secret";
// 阿里云OSS服务的BucketName
private static final String BUCKET_NAME = "your_bucket_name";
// OSS客户端实例
private OSS ossClient;
// 初始化OSS客户端
public void init() {
ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
}
// 关闭OSS客户端
public void close() {
ossClient.shutdown();
}
// 分片上传文件
public void multipartUpload(String objectName, InputStream inputStream, long fileSize) throws IOException {
// 初始化MultipartUploadRequest
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(BUCKET_NAME, objectName);
InitiateMultipartUploadResult result = ossClient.initiateMultipartUpload(request);
// 获取UploadId
String uploadId = result.getUploadId();
// 设置每个Part的大小,最小为100KB
final long partSize = 1024 * 100L;
// 计算文件的Part个数
int partCount = (int) (fileSize / partSize);
if (fileSize % partSize != 0) {
partCount++;
}
List<PartETag> partETags = new ArrayList<>();
for (int i = 0; i < partCount; i++) {
long startPos = i * partSize;
long curPartSize = Math.min(partSize, fileSize - startPos);
InputStream partInputStream = new FilePartInputStream(inputStream, startPos, curPartSize);
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(BUCKET_NAME);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setPartNumber(i + 1);
uploadPartRequest.setInputStream(partInputStream);
uploadPartRequest.setPartSize(curPartSize);
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
partETags.add(uploadPartResult.getPartETag());
}
// 完成分片上传
CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(BUCKET_NAME, objectName, uploadId, partETags);
ossClient.completeMultipartUpload(completeMultipartUploadRequest);
}
// 获取文件上传进度
public long getUploadProgress(String objectName) {
// 获取文件大小
ObjectMetadata metadata = ossClient.getObjectMetadata(BUCKET_NAME, objectName);
long fileSize = metadata.getContentLength();
// 获取已上传的Part信息
ListPartsRequest listPartsRequest = new ListPartsRequest(BUCKET_NAME, objectName, null);
PartListing partListing = ossClient.listParts(listPartsRequest);
List<PartSummary> partSummaries = partListing.getParts();
// 计算已上传的大小
long uploadedSize = 0;
for (PartSummary partSummary : partSummaries) {
uploadedSize += partSummary.getSize();
}
// 计算上传进度
long progress = (long) ((double) uploadedSize / fileSize * 100);
return progress;
}
// 自定义的输入流,用于分片上传文件
private static class FilePartInputStream extends InputStream {
private InputStream inputStream;
private long startPos;
private long curPartSize;
private long pos;
public FilePartInputStream(InputStream inputStream, long startPos, long curPartSize) {
this.inputStream = inputStream;
this.startPos = startPos;
this.curPartSize = curPartSize;
this.pos = 0;
}
@Override
public int read() throws IOException {
if (pos >= curPartSize) {
return -1;
}
int read = inputStream.read();
pos++;
return read;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (pos >= curPartSize) {
return -1;
}
int readLen = (int) Math.min(len, curPartSize - pos);
int read = inputStream.read(b, off, readLen);
pos += read;
return read;
}
@Override
public void close() throws IOException {
super.close();
inputStream.close();
}
}
}
```
3. 创建一个名为UploadController的控制器,用于处理文件上传和进度查询请求:
```java
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("/upload")
public class UploadController {
@Autowired
private OSSUtil ossUtil;
// 处理文件上传请求
@PostMapping("/file")
public String uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
// 初始化OSS客户端
ossUtil.init();
// 分片上传文件
String objectName = file.getOriginalFilename();
ossUtil.multipartUpload(objectName, file.getInputStream(), file.getSize());
// 关闭OSS客户端
ossUtil.close();
return "success";
}
// 处理进度查询请求
@GetMapping("/progress")
public long getUploadProgress(@RequestParam("objectName") String objectName) {
// 获取上传进度
long progress = ossUtil.getUploadProgress(objectName);
return progress;
}
}
```
4. 在前端页面中使用HTML5的进度条组件,结合后端实现的上传进度查询接口,展示文件上传的进度。例如,以下是一个基于Vue.js的示例代码:
```html
<template>
<div>
<input type="file" @change="handleFileChange">
<button @click="uploadFile">上传</button>
<div v-show="showProgress">
<progress :value="progress" max="100"></progress>
<span>{{ progress }}%</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
file: null,
showProgress: false,
progress: 0,
intervalId: null
}
},
methods: {
handleFileChange(event) {
this.file = event.target.files[0]
},
uploadFile() {
this.showProgress = true
let formData = new FormData()
formData.append('file', this.file)
axios.post('/upload/file', formData)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
this.intervalId = setInterval(() => {
axios.get('/upload/progress', { params: { objectName: this.file.name }})
.then(response => {
this.progress = response.data
if (this.progress >= 100) {
clearInterval(this.intervalId)
}
})
.catch(error => {
console.log(error)
})
}, 1000)
}
}
}
</script>
```
以上就是Java SpringBoot框架下实现OSS文件分片上传和进度条展示的全代码示例。
阅读全文