阿里雲OSS斷點續傳(Java版本)
在工作中發現開發的某項功能在用戶網絡環境差的時候部分圖片無法顯示,通過Review代碼之后發現原來是圖片上傳到了國外的亞馬遜服務器上,經過討論決定將圖片上傳到國內阿里雲的OSS上,下面是通過上網查找資料和看官網API之后寫的一個Java版本的斷點續傳的demo。
注意:這里是上傳到你自己的服務器后,然后再上傳到阿里雲OSS,不是直接通過前端上傳的
首先 , 添加maven
<!-- 阿里雲OSS服務 -->
<!-- https://mvnrepository.com/artifact/com.aliyun.oss/aliyun-sdk-oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.3.0</version>
</dependency>
根據官網斷點續傳寫demo
阿里雲官網:https://help.aliyun.com/document_detail/31886.html?spm=a2c4g.11186623.6.564.52d735542GHP78
import java.util.Properties;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.Callback;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.UploadFileRequest;
import com.tinno.gamecenter.biz.util.PropertiesHelper;
import com.tinno.gamecenter.common.beans.OssUploadBean;
import com.tinno.gamecenter.core.exception.TinnoCommonException;
/**
* 阿里雲文件存儲服務器相關
* @Title: OssUtil.java
* @author 王武明
* @date 2018年9月18日 下午1:50:01
* @version V1.0
*/
public class OssUtil
{
/**
* 日志
*/
private static Logger logger = Logger.getLogger(OssUtil.class);
// 阿里雲API的內或外網域名
private static String ALIYUN_OSS_ENDPOINT;
// 阿里雲API的密鑰Access Key ID
private static String ALIYUN_ACCESS_KEY_ID;
// 阿里雲API的密鑰Access Key Secret
private static String ALIYUN_OSS_ACCESS_KEY_SECRET;
// bucket
private static String ALIYUN_OSS_BUCKET_ID;
static
{
Properties properties = PropertiesHelper.loadPropertiesFile("/config.properties");
ALIYUN_OSS_ENDPOINT = properties.containsKey("ALIYUN_OSS_ENDPOINT") == false ? "" : PropertiesHelper.getString("ALIYUN_OSS_ENDPOINT", null, properties);
ALIYUN_ACCESS_KEY_ID = properties.containsKey("ALIYUN_ACCESS_KEY_ID") == false ? "" : PropertiesHelper.getString("ALIYUN_ACCESS_KEY_ID", null, properties);
ALIYUN_OSS_ACCESS_KEY_SECRET = properties.containsKey("ALIYUN_OSS_ACCESS_KEY_SECRET") == false ? ""
: PropertiesHelper.getString("ALIYUN_OSS_ACCESS_KEY_SECRET", null, properties);
ALIYUN_OSS_BUCKET_ID = properties.containsKey("ALIYUN_OSS_BUCKET_ID") == false ? "" : PropertiesHelper.getString("ALIYUN_OSS_BUCKET_ID", null, properties);
}
/**
* 獲取阿里雲OSS客戶端對象
* @return OSSClient 返回類型
*/
@SuppressWarnings("deprecation")
public static final OSSClient getOSSClient()
{
return new OSSClient(ALIYUN_OSS_ENDPOINT, ALIYUN_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET);
}
/**
* 新建Bucket --Bucket權限:私有
* @param bucketName bucket名稱
* @return true 新建Bucket成功
*/
public static final boolean createBucket(OSSClient client)
{
Bucket bucket = client.createBucket(ALIYUN_OSS_BUCKET_ID);
return ALIYUN_OSS_BUCKET_ID.equals(bucket.getName());
}
/**
* 刪除Bucket
* @param bucketName bucket名稱
*/
public static final void deleteBucket(OSSClient client, String bucketName)
{
client.deleteBucket(bucketName);
logger.error("刪除" + bucketName + "Bucket成功");
}
/**
* 通過文件名判斷並獲取OSS服務文件上傳時文件的contentType
* @param fileName 文件名
* @return 文件的contentType
*/
public static final String getContentType(String fileName)
{
String fileExtension = fileName.substring(fileName.lastIndexOf("."));
if (".bmp".equalsIgnoreCase(fileExtension))
return "image/bmp";
if (".gif".equalsIgnoreCase(fileExtension))
return "image/gif";
if (".jpeg".equalsIgnoreCase(fileExtension))
return "image/jpeg";
if (".jpg".equalsIgnoreCase(fileExtension))
return "image/jpg";
if (".png".equalsIgnoreCase(fileExtension))
return "image/png";
if (".html".equalsIgnoreCase(fileExtension))
return "text/html";
if (".txt".equalsIgnoreCase(fileExtension))
return "text/plain";
if (".vsd".equalsIgnoreCase(fileExtension))
return "application/vnd.visio";
if (".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension))
return "application/vnd.ms-powerpoint";
if (".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension))
return "application/msword";
if (".xml".equalsIgnoreCase(fileExtension))
return "text/xml";
return "text/html";
}
/**
* 向阿里雲的OSS存儲中存儲文件
* @author 王武明
* @date 2018年9月18日 下午4:00:22
* @param client OSS客戶端
* @param file 上傳文件
* @param bucketName bucket名稱
* @param diskName 上傳文件的目錄 --bucket下文件的路徑
* @return String 唯一MD5數字簽名
* @throws TinnoCommonException
* @return String 返回類型
*/
public static final String uploadObject2OSS(OssUploadBean ossUploadBean) throws TinnoCommonException
{
OSSClient ossClient = ossUploadBean.getOssClient();
String fileName = ossUploadBean.getFileName();
String localePath = ossUploadBean.getLocalePath();
String checkpointFile = ossUploadBean.getCheckpointFile();
String key = ossUploadBean.getKey();
Callback callback = ossUploadBean.getCallback();
try
{
UploadFileRequest uploadFileRequest = new UploadFileRequest(ALIYUN_OSS_BUCKET_ID, key);
// 指定上傳的內容類型
ObjectMetadata metadata = new ObjectMetadata();
metadata.setCacheControl("no-cache");
metadata.setHeader("Pragma", "no-cache");
metadata.setContentEncoding("utf-8");
metadata.setContentType(getContentType(fileName));
// 設置存儲空間名稱
uploadFileRequest.setBucketName(ALIYUN_OSS_BUCKET_ID);
// 設置文件名稱。
//uploadFileRequest.setKey("<yourObjectName>");
// 指定上傳的本地文件。
uploadFileRequest.setUploadFile(localePath);
// 指定上傳並發線程數,默認為1。
uploadFileRequest.setTaskNum(5);
// 指定上傳的分片大小,范圍為100KB~5GB,默認為文件大小/10000。
uploadFileRequest.setPartSize(1 * 1024 * 1024);
// 開啟斷點續傳,默認關閉。
uploadFileRequest.setEnableCheckpoint(true);
// 記錄本地分片上傳結果的文件。開啟斷點續傳功能時需要設置此參數,上傳過程中的進度信息會保存在該文件中,
// 如果某一分片上傳失敗,再次上傳時會根據文件中記錄的點繼續上傳。
// 上傳完成后,該文件會被刪除。默認與待上傳的本地文件同目錄,為uploadFile.ucp。
if (StringUtils.isEmpty(checkpointFile))
{
uploadFileRequest.setCheckpointFile("uploadFile.ucp");
}else {
uploadFileRequest.setCheckpointFile(checkpointFile);
}
// 文件的元數據。
uploadFileRequest.setObjectMetadata(metadata);
// 設置上傳成功回調,參數為Callback類型。
if (callback != null)
{
uploadFileRequest.setCallback(callback);
}
// 斷點續傳上傳。
try
{
ossClient.uploadFile(uploadFileRequest);
}
catch (Throwable e)
{
e.printStackTrace();
}
}
catch (Exception e)
{
logger.error("上傳阿里雲OSS文件服務器出錯!", e);
throw new TinnoCommonException("上傳阿里雲OSS文件服務器出錯!", e);
}
finally
{
ossClient.shutdown();
}
return String.format("https://%s.%s/%s", ALIYUN_OSS_BUCKET_ID,ALIYUN_OSS_ENDPOINT,key);
}
}
JavaBean, 這里面用來lombok插件,所以無需手動設置set和get
import java.io.File;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.Callback;
import lombok.Data;
@Data
public class OssUploadBean
{
/**
* 阿里雲Oss上傳客戶端
*/
private OSSClient ossClient;
/**
* 需要上傳文件到的某一個桶
*/
private Bucket bucket;
/**
* 回調參數
* 設置文檔:https://help.aliyun.com/document_detail/31989.html
*/
private Callback callback;
/**
* 需要上傳的文件
*/
private File file;
/**
* 文件名稱
*/
private String fileName;
/**
* 文件所在的本地路徑
*/
private String localePath;
/**
* 記錄本地分片上傳結果的文件。開啟斷點續傳功能時需要設置此參數,上傳過程中的進度信息會保存在該文件中,
* 如果某一分片上傳失敗,再次上傳時會根據文件中記錄的點繼續上傳。
* 上傳完成后,該文件會被刪除。默認與待上傳的本地文件同目錄,為uploadFile.ucp。
*/
private String checkpointFile;
/**
* 上傳到某一個bucket文件夾下
*/
private String key;
}
config.properties相關配置
#OSS
ALIYUN_OSS_ENDPOINT=oss-cn-beijing.aliyuncs.com
ALIYUN_ACCESS_KEY_ID=<your aliyun access key id>
ALIYUN_OSS_ACCESS_KEY_SECRET=<your access key secret>
ALIYUN_OSS_BUCKET_ID=<your bucket id>
實際使用Test Method
//上傳文件到阿里雲OSS服務器
private String uploadOSS(String fileName, String localePath) throws TinnoCommonException
{
try
{
OSSClient ossClient = OssUtil.getOSSClient();
OssUploadBean ossUploadBean = new OssUploadBean();
// 文件名稱
ossUploadBean.setFileName(fileName);
// 文件上傳到自己的服務器的地址
ossUploadBean.setLocalePath(localePath);
ossUploadBean.setOssClient(ossClient);
ossUploadBean.setKey(String.format("%s/%s","folder",fileName));//上傳到bucket下的某一個路徑
// 返回上傳到的oss路徑
return OssUtil.uploadObject2OSS(ossUploadBean);
}
catch (Exception e)
{
logger.error("上傳阿里雲服務器出錯!", e);
throw new TinnoCommonException("上傳阿里雲服務器出錯!", e);
}
}
編寫代碼時候遇到的一些問題
1. 設置callback:因為這里我不需要callback所以沒有引入callback,這里附上官網設置callback的鏈接:
https://help.aliyun.com/document_detail/31989.html
2. 上傳文件后如何訪問:代碼在上面,這里附上官網鏈接:
https://help.aliyun.com/knowledge_detail/39607.html