阿里云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