pom.xml配置
com.aliyun.oss
aliyun-sdk-oss
3.8.1
如果引入oss 与 net.sf.jso冲突 ,可添加以下代码:
net.sf.json-lib
json-lib
2.4
jdk15
逻辑代码
public ResultVM uploadVideo(HttpServletRequest request) throws Exception {
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
MultipartFile file = multiRequest.getFile("file");
java.io.File sampleFile = ImageWordsUtil.fileToMultipartFile(file);
String filePath = "video" + "/";
if (file != null) {
//单个文件最大
String fileName = ossService.genFileNameByUserId(filePath, file.getOriginalFilename());
Map map = new HashMap<>();
map.put("noDomainUrls", ossProperties.getDomainName() + fileName);
log.info("url为" + ossProperties.getDomainName() + fileName);
new Thread(new Runnable() {
@Override
public void run() {
try {
ossMultipartUploadService.uploadVideo(sampleFile,fileName);
}catch (Exception e){
e.getMessage();
}
}
}).start();
log.info("url为输出" + ossProperties.getDomainName() + fileName);
return ResultVMUtil.success(map);
} else {
log.warn("上传文件为空");
return ResultVMUtil.error(ResultEnum.UPLOAD_FILE_IS_NULL);
}
}
public static File fileToMultipartFile(MultipartFile multipartFile)throws IOException {
String fileName = multipartFile.getOriginalFilename();
String fileEndName = fileName.substring(fileName.lastIndexOf("."));
String result= DateUtil.getDateFormatterStr();
Path path = Paths.get( fileName.substring(0,fileName.indexOf("."))+"-"+ result + fileEndName);
byte[] bytes = multipartFile.getBytes();
// 文件写入指定路径
Files.write(path, bytes);
File file = new File(path.toString());
return file;
}
import com.aliyun.oss.*;
import com.aliyun.oss.model.*;
import com.ysx.zzedu.common.config.OssProperties;
import com.ysx.zzedu.common.utils.DateUtil;
import com.ysx.zzedu.common.utils.ImageWordsUtil;
import com.ysx.zzedu.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @author
* @version 1.0
* @info oss上传文件
* @since 1.0
*/
@Slf4j
@Service
public class OssMultipartUploadService {
@Autowired
private OssProperties ossProperties;
private OSS client = null;
//表示上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg
private String objectName = "";
// 定长线程池
private ExecutorService executorService = Executors.newFixedThreadPool(5);
private static List partETags = null;
private static final int partSize = 5 * 1024 * 1024; // 5MB 分片大小
public String uploadVideo(File sampleFile,String localPath){
String endPoint = ossProperties.getEndPoint();
String accessKeyId = ossProperties.getAccessKeyId();
String accessKeySecret = ossProperties.getAccessKeySecret();
String bucketName = ossProperties.getBucketName();
long start = System.currentTimeMillis();
objectName = localPath;
ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
conf.setIdleConnectionTime(5000);
client = new OSSClientBuilder().build(endPoint, accessKeyId,accessKeySecret,conf);
String fileUrl = null;
try {
String uploadId = claimUploadId();
log.info("申请一个新的上传id:" + uploadId);
// 文件大小
long fileLength = sampleFile.length();
// 分片总数(总共分几个部分)
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
if (partCount > 10000) {
log.warn("partCount总数不应超过10000");
return null;
} else {
log.info("文件总共分片数:" + partCount);
}
partETags = Collections.synchronizedList(new ArrayList(partCount));
CountDownLatch latch = new CountDownLatch(partCount);
log.info("***************开始准备上传************");
for (int i = 0; i < partCount; i++) {
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
executorService.execute(new PartUploader(sampleFile, startPos, curPartSize, i + 1, uploadId, latch));
}
latch.await();
if (partETags.size() != partCount) {
StringBuilder partETagsStr = new StringBuilder("(");
for (PartETag item : partETags) {
partETagsStr.append(item.getPartNumber()).append(",");
}
partETagsStr.append(")");
log.info(String.format("partCount:%s*******,partEtages:%s*******,partETagsSize:%s", partCount, partETagsStr, partETags.size()));
throw new IllegalStateException("上传多个部分失败,因为有些部分还没有完成");
} else {
log.info("成功地将多个部分合并上传到一个名为的对象中 " + objectName);
}
listAllParts(uploadId);
completeMultipartUpload(uploadId);
log.info("获取一个对象");
long end = System.currentTimeMillis();
// 生成文件地址
// client.getObject(new GetObjectRequest(bucketName, key), new File(localFilePath));
boolean isFileExist = client.doesObjectExist(bucketName, objectName);
if (isFileExist) {
fileUrl = ossProperties.getDomainName() + objectName;
log.info(String.format("上传成功*****耗时:%s*****,文件地址:%s",((end - start) / 1000),fileUrl));
} else {
throw new Exception("上传失败,文件不存在");
}
} catch (OSSException oe) {
log.error(oe.getMessage(), oe);
} catch (ClientException ce) {
log.error(ce.getErrorMessage(), ce);
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
if (client != null) {
client.shutdown();
}
if (sampleFile != null) {
sampleFile.delete();
}
partETags.clear();
partETags = null;
return fileUrl;
}
}
private class PartUploader implements Runnable {
private File localFile;
private long startPos;
private long partSize;
private int partNumber;
private String uploadId;
private CountDownLatch latch;
public PartUploader(File localFile, long startPos, long partSize, int partNumber, String uploadId,CountDownLatch latch) {
this.localFile = localFile;
this.startPos = startPos;
this.partSize = partSize;
this.partNumber = partNumber;
this.uploadId = uploadId;
this.latch = latch;
}
@Override
public void run() {
InputStream instream = null;
try {
instream = new FileInputStream(this.localFile);
instream.skip(this.startPos);
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(ossProperties.getBucketName());
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(this.uploadId);
uploadPartRequest.setInputStream(instream);
uploadPartRequest.setPartSize(this.partSize);
uploadPartRequest.setPartNumber(this.partNumber);
UploadPartResult uploadPartResult = client.uploadPart(uploadPartRequest);
System.out.println("Part#" + this.partNumber + " 完成\n");
synchronized (partETags) {
partETags.add(uploadPartResult.getPartETag());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (instream != null) {
try {
instream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
latch.countDown();
}
}
}
private File createSampleFile() throws IOException {
File file = File.createTempFile("oss-java-sdk-", ".txt");
file.deleteOnExit();
Writer writer = new OutputStreamWriter(new FileOutputStream(file));
for (int i = 0; i < 1000000; i++) {
writer.write("abcdefghijklmnopqrstuvwxyz\n");
writer.write("0123456789011234567890\n");
}
writer.close();
return file;
}
private String claimUploadId() {
// 创建InitiateMultipartUploadRequest对象。
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(ossProperties.getBucketName(), objectName);
InitiateMultipartUploadResult result = client.initiateMultipartUpload(request);
return result.getUploadId();
}
private void completeMultipartUpload(String uploadId) {
// Make part numbers in ascending order
Collections.sort(partETags, new Comparator() {
@Override
public int compare(PartETag p1, PartETag p2) {
return p1.getPartNumber() - p2.getPartNumber();
}
});
System.out.println("Completing to upload multiparts\n");
// 创建CompleteMultipartUploadRequest对象。
// 在执行完成分片上传操作时,需要提供所有有效的partETags。OSS收到提交的partETags后,会逐一验证每个分片的有效性。当所有的数据分片验证通过后,OSS将把这些分片组合成一个完整的文件。
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(ossProperties.getBucketName(), objectName, uploadId, partETags);
client.completeMultipartUpload(completeMultipartUploadRequest);
}
private void listAllParts(String uploadId) {
System.out.println("Listing all parts......");
ListPartsRequest listPartsRequest = new ListPartsRequest(ossProperties.getBucketName(), objectName, uploadId);
PartListing partListing = client.listParts(listPartsRequest);
int partCount = partListing.getParts().size();
for (int i = 0; i < partCount; i++) {
PartSummary partSummary = partListing.getParts().get(i);
System.out.println("\tPart#" + partSummary.getPartNumber() + ", ETag=" + partSummary.getETag());
}
System.out.println();
}
}