构建基于阿里云OSS文件上传服务
转载请注明来源:http://blog.csdn.net/loongshawn/article/details/50710132
1. 阿里云OSS服务介绍
对象存储(Object Storage Service,简称OSS),是阿里云提供的海量、安全和高可靠的云存储服务。在OSS中每一个文件都有一个key。通过这个key来指向不同的文件对象。
同一时候大家要明确。在OSS中是没有目录的概念。假设你在web管理平台上看到了目录的形式,那是阿里云为了大家的操作习惯虚构出来了。
如你提交的key为“/attachment/2016/123.txt”,那么在web管理平台上你能够看到上述以“/”分开的目录形式,事实上在OSS他的key就是“/attachment/2016/123.txt”
2. 阿里云OSS Java SDK
阿里云官方有针对不同语言设计的SDK包,本文使用java SDK。
具体SDK介绍參看官网链接:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/preface.html?
<!-- OSS Java SDK -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.1.0</version>
</dependency>
3. 怎样使用OSS
阿里云OSS服务,通过自身提供的Client来实现上传和下载。
所以在使用OSS服务上传文件时,须要构建三个类:Client类、Config类、上传类。
4. 构建OSS Client类
採用单例模式构建OSSClient。
package com.autonavi.oss.client;
import com.aliyun.oss.OSSClient;
import com.autonavi.constants.Constant;
import com.autonavi.oss.conf.DefaultClientConfiguration;
public class DefaultOSSClient {
/*
* Constructs a client instance with your account for accessing OSS
*/
private static OSSClient client = new OSSClient(Constant.endpoint, Constant.accessKeyId, Constant.accessKeySecret,DefaultClientConfiguration.getDefalutClientConfig());
private DefaultOSSClient() {
}
public static OSSClient getDefaultOSSClient(){
if(client == null){
client = new OSSClient(Constant.endpoint, Constant.accessKeyId, Constant.accessKeySecret,DefaultClientConfiguration.getDefalutClientConfig());
}
return client;
}
public static void shutdownOSSClient(){
client.shutdown();
client = null;
}
}
5. 构建OSS Config类
配置OSSClient所须要的属性。
package com.autonavi.oss.conf;
import com.aliyun.oss.ClientConfiguration;
public class DefaultClientConfiguration {
private static final ClientConfiguration conf = new ClientConfiguration();
private DefaultClientConfiguration() {
// Set the maximum number of allowed open HTTP connections
conf.setMaxConnections(100);
// Set the amount of time to wait (in milliseconds) when initially establishing
// a connection before giving up and timing out
conf.setConnectionTimeout(5000);
// Set the maximum number of retry attempts for failed retryable requests
conf.setMaxErrorRetry(3);
// Set the amount of time to wait (in milliseconds) for data to betransfered over
// an established connection before the connection times out and is closed
conf.setSocketTimeout(2000);
}
public static ClientConfiguration getDefalutClientConfig(){
return conf;
}
}
6. 构建OSS 文件上传类
OSS文件上传,支持两种方式:1、File;2、InputStream,所以设计了两种模式相应的方法,大同小异。上传类中须要注意一点就是并发的问题。由于当前存储文件是依照时间戳来存储,所以对方法中的这种方法getCurrentTimeStamp()加了synchronized同步处理。
package com.autonavi.oss.put;
import java.io.File;
import java.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.PutObjectRequest;
import com.autonavi.constants.Constant;
import com.autonavi.oss.client.DefaultOSSClient;
import com.autonavi.utils.Date2Str;
/**
* @author loongshawn
* @date 2016-01-28
* @category OSS文件上传。支持两种方式:1、File。2、InputStream
* @paras ArrayList<File> files
*/
public class OSSUpload {
private static final Logger logger = LoggerFactory.getLogger(OSSUpload.class);
public static String put1(File file){
String return_key = null;
try {
OSSClient client = DefaultOSSClient.getDefaultOSSClient();
if(file != null){
String fileName = file.getName();
/**
* getCurrentTimeStamp()方法为同步方法,确保时间戳的唯一性。
*/
String timeStamp = Date2Str.getCurrentTimeStamp();
String timeDate = Date2Str.getCurrentDate5();
String key = Constant.bashFilePath + timeDate + timeStamp +"/"+fileName;
client.putObject(new PutObjectRequest(Constant.bucketName, key, file));
}
DefaultOSSClient.shutdownOSSClient();
} catch (ClientException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
logger.info("OSSUpload.put1 error:" + e.toString());
return null;
}
return return_key;
}
public static String put2(InputStream in, String filename){
String return_key = null;
try {
OSSClient client = DefaultOSSClient.getDefaultOSSClient();
if(in != null){
String fileName = filename;
/**
try {
fileName = new String(filename.getBytes("ISO-8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
**/
/**
* getCurrentTimeStamp()方法为同步方法,确保时间戳的唯一性。
*/
String timeStamp = Date2Str.getCurrentTimeStamp();
String timeDate = Date2Str.getCurrentDate5();
String key = Constant.bashFilePath + timeDate + timeStamp +"/"+fileName;
client.putObject(new PutObjectRequest(Constant.bucketName, key, in));
return_key = key;
}
DefaultOSSClient.shutdownOSSClient();
} catch (ClientException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
logger.info("OSSUpload.put2 error:" + e.toString());
return null;
}
return return_key;
}
}
同步获取时间戳的方法。以防止并发时出现文件遗漏。
// 同步获取时间戳的方法。即一个时刻仅仅有一个方法被调用。即产生唯一时间戳
public static synchronized String getCurrentTimeStamp(){
String time = getDate(0,3);
return time;
}
7. 文件上传測试
7.1. 方式一:代码測试
public class FileUpload {
public static void main(String[] args){
try {
uploadOSS();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void uploadOSS() throws ClientProtocolException, IOException{
HttpPost httpPost = new HttpPost("http://127.0.0.1:7001/test/autonavi/shanghai/api/attachment/oss/");
httpPost.addHeader("key","123);
httpPost.addHeader("user","123");
httpPost.addHeader("method","123");
httpPost.addHeader("filename",new String("黄山[哈哈].jpg".getBytes("UTF-8"),"ISO-8859-1"));
httpPost.addHeader("type","01");
FileEntity reqEntity = new FileEntity(new File("/Users/123/Pictures/Huangshan.jpg"));
httpPost.setEntity(reqEntity);
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(httpPost);
System.out.println(response);
}
上传成功截图:
7.2. 方式二:工具提交測试
利用RestFul Client工具測试
上传成功截图:
8. 后记
当然编写的服务还有非常多不足之处,希望看过的朋友指正。