Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
SNDA Storage Service SDK for Java
Java
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
src
.gitignore
CHANGELOG
README.md
pom.xml

README.md

盛大云存储服务Java SDK

盛大云存储服务Java SDK由盛大官方提供,开发者可以利用该工具包实现:

  1. 管理Bucket信息
  2. 上传与下载Object数据
  3. 生成与设置Bucket Policy
  4. 生成预签名(Presigned)的可公开访问的URL

特点

  1. DSL(Fluent Interface)风格的API,简洁易用
  2. 支持Access Policy Language,通过DSL风格的API生成Bucket Policy
  3. 支持大文件上传(最大5TB),自动通过Multipart Upload机制上传大文件,对开发者透明
  4. 提供了独立的签名与认证模块供开发者使用
  5. 支持HTTPS安全网络访问
  6. 无需配置Endpoint,自动支持多盛大云存储服务的多IDC
  7. 支持限速传输

下载

目前最新的版本是2012年09月24日发布的2.0.0:

  1. snda-cloud-storage-java-sdk-2.0.0.jar 二进制发布包
  2. snda-cloud-storage-java-sdk-2.0.0.zip 包含源代码,第三方依赖,Javadoc等内容的发布包

Maven

<dependency>
    <groupId>com.snda</groupId>
    <artifactId>snda-cloud-storage-java-sdk</artifactId>
    <version>2.0.0</version>
</dependency>

配置Sonatype仓库

<repository>
    <id>sonatype-service</id>
    <url>https://oss.sonatype.org/service/local/repositories/releases/content</url>
</repository>

使用

盛大云存储服务Java SDK提供了DSL风格的Java API,易于上手,简单高效。其核心为SNDAStorage对象,开发者通过该对象提供的多种方法来访问盛大云存储服务。

构建SNDAStorage对象

SNDAStorage storage = new SNDAStorageBuilder().credential(yourAccessKeyId, yourSecretAccessKey).build();

更多的设置:

SNDAStorage storage = new SNDAStorageBuilder().
    credential(yourAccessKeyId, yourSecretAccessKey).
    https().                        //启用HTTPS
    bytesPerSecond(64 * 1024).      //限制每秒传输速率为64KB
    connectionTimeout(10 * 1000).   //设置ConnectionTimeout为10秒
    soTimeout(30 * 1000).           //设置SoTimeout为30秒
    build();

SNDAStorage对象内部维护了一组HTTP连接池,在不使用该对象时,应该调用其destory方法销毁该对象,

storage.destory();

列出所有的Bucket

for (BucketSummary each : storage.listBuckets()) {
    String name = each.getName();
}

Bucket相关操作

在默认的Location节点中创建名为mybucket的Bucket

storage.bucket("mybucket").create();

在华东一节点创建Bucket

storage.bucket("mybucket").location(Location.HUADONG_1).create();

查看Location

storage.bucket("mybucket").location().get();    

删除Bucket

storage.bucket("mybucket").delete();            

设置Bucket Policy

storage.bucket("mybucket").policy(myPolicy).set();

获取Bucket Policy

storage.bucket("mybucket").policy().get();

删除Bucket Policy

storage.bucket("mybucket").policy().delete();   

根据条件列出Objects

ListBucketResult result = storage.              
    bucket("mybucket").
    prefix("upload/").
    delimiter("/").
    maxKeys(25).
    listObjects();                                  

根据条件列出Multipart Uploads

ListMultipartUploadsResult result = storage.    
    bucket("mybucket").
    prefix("data/").
    maxUploads(50).
    listMultipartUploads();                         

Object相关的操作

上传数据

storage.bucket("mybucket").object("data/upload/pic.jpg").entity(new File("d:\\user\\my_picture.jpg")).upload();

自定义Metadata

storage.bucket("mybucket").object("data/upload/mydata").
    contentType("application/octet-stream").    
    contentMD5("ABCDEFGUVWXYZ").
    contentLanguage("en").
    metadata("x-snda-meta-foo", "bar").
    metadata("x-snda-meta-creation", new DateTime()).
    metadata("x-snda-meta-author", "wangzijian@snda.com").
    entity(2048L, inputStream).
    upload();

下载数据

SNDAObject object = null;
try {
    object = storage.bucket("mybucket").object("data/upload/pic.jpg").download();
    read(object.getContent());
} finally {
    Closeables.closeQuietly(object);
}

SNDAObject实现了java.io.Closeable接口,其内部持有了代表Object内容的InputStream,需要在使用完毕时关闭。

下载至本地硬盘

storage.bucket("mybucket").object("data/pic.jpg").download().to(new File("~/download/my_pic.jpg"));

条件下载(Conditional GET)

storage.bucket("mybucket").object("norther.mp3").ifModifedSince(new DateTime(2012, 10, 7, 20, 0, 0)).download();

分段下载(Range GET)

storage.bucket("mybucket").object("norther.mp3").range(1000, 5000).download();

获取Object信息与Metadata(HEAD Object)

SNDAObjectMetadata metadata = storage.bucket("mybucket").object("music/norther.mp3").head();

更新Object信息与Metadata

storage.bucket("mybucket").object("music/norther.mp3").
    contentType("audio/mpeg").
    metadata("x-snda-meta-nation", "Finland").
    update();

复制Object

storage.bucket("mybucket").object("book/english.txt").
    copySource("otherbucket", "data/edu/main.txt");
    replaceMetadata().
    contentType("text/plain").
    metadata("x-snda-meta-author", "Jack Jackson").
    copy();

Bucket Policy

盛大云存储SDK提供了强大的Bucket Policy构建器,开发者可以轻易生成和设置所需要的Bucket Policy。

加入静态引入

import static com.snda.storage.policy.fluent.impl.Conditions.*

允许匿名用户下载该Bucket中key以public作为前缀的所有Object,同时限定User-Agent为Android或IOS,防盗链Referer设置为.mycompany.com/

Statement statement = Statement.allow().anyone().perform("storage:GetObject").to("srn:snda:storage:::mybucket/public/*").
    where(userAgent().equals("Android", "IOS")).
    and(referer().equals("*.mycompany.com/*")).
    identifed("public-get-object");

storage.bucket("mybucket").policy(new Policy().
    withRandomId().
    withStatement(statement)).
    set();

允许匿名用户通过HTTPS下载该Bucket中的所有Object,且请求时间必须在2012年10月1日0点至2012年10月8日0点之间:

Statement.allow().anyone().perform("storage:GetObject").to("srn:snda:storage:::mybucket/*").
    where(secureTransport().bool(true)).
    and(currentTime().greaterThan(new DateTime(2012, 10, 1, 0, 0, 0))).
    and(currentTime().lessThan(new DateTime(2012, 10, 8, 0, 0, 0))).
    identifed("public-get-object-with-time-restriction");

设置请求的IP必须在指定的"192.168.176.0/24"范围内:

Statement.allow().anyone().perform("storage:GetObject").to("srn:snda:storage:::mybucket/*").
    where(sourceIp().ipAddress("192.168.176.0/24")).
    identifed("public-get-object-with-connection-restriction");

生成预签名的URI

盛大云存储提供了一种基于查询字串(Query String)的认证方式,即通过预签名(Presigned)的方式,为要发布的Object生成一个带有认证信息的URI,并将它分发给第三方用户来实现公开访问。

SDK中提供了PresigendURIBuilder来构造预签名URI。

URI uri = storage.presignedURIBuilder().
    bucket("mybucket").
    key("hello_world.mp4").
    expires(new DateTime().plusMinutes(5))
    build();

生成的URI如下:

http://storage-huadong-1.sdcloud.cn/mybucket/hello_world.mp4?Expires=1348044780&SNDAAccessKeyId=norther&Signature=SJawXv5QdQHcFrTqnx3RpmTN9WI%3D

Entity

Entity代表要上传的Object的内容,由内容与长度组成,接口定义如下:

public interface Entity extends InputSupplier<InputStream> {

    long getContentLength();

    InputStream getInput() throws IOException;
}

getContentLength方法返回该Entity的长度,盛大云存储服务要求上传的数据必须事先指定其长度,最大不得超过5TB。

getInput方法继承自Google Guava的InputSupplier。 InputSupplier代表Entity的内容,是一个打开InputStream的回调(Callback)。 在云存储SDK的不同模块之间,我们只传递InputSupplier的引用,而不是直接传递InputStream。 这是一种高效并且灵活的使用流的方式,因为只有在必要的时候,应用才会调用InputSupplier的getInput方法来打开一个新的InputStream,并保证该InputStream在使用完毕时能被正确的关闭。

下面的样例中,盛大云存储SDK只在必须要的情况下,才会调用getInput来打开流。

object.bucket("mybucket").object("key").
    contentType("video/mp4").
    entity(65535, new InputSupplier<InputStream>() {
        @Override
        public InputStream getInput() throws IOException {
            return openStream();
        }
    }).
    upload();

云存储SDK提供了3种默认的Entity实现,包括InputSupplierEntity, InputStreamEntity,与 FileEntity

参考FileEntity的实现:

public class FileEntity implements Entity {

    private final File file;

    public FileEntity(File file) {
        this.file = checkNotNull(file);
    }

    @Override
    public long getContentLength() {
        return file.length();
    }

    @Override
    public InputStream getInput() throws IOException {
        return new FileInputStream(file);
    }
}

注意 InputStreamEntity并不关闭其持有的InputStream对象,这样的做法符合IO Stream使用的最佳实现,即:关闭自己打开的流

样例如下:

InputStream inputStream = null;
try {
    inputStream = openInputStream(); //用户应负责关闭自己所打开的流,盛大云存储SDK并不会关闭用户传入的InputStream对象
    storage.bucket("mybucket").object("key").entity(256, inputStream).upload();
} finally {
    Closeables.closeQuietly(inputStream);
}

Multipart Upload API

开发这使用盛大云存储SDK上传文件时,SDK会透明的使用Multipart Upload实现对大文件上传,一般情况下用户不需要自己来使用Multipart Upload API。

若开发者有自己使用Multipart Upload的需求,可以参看下面的使用样例:

初始化Multipart Upload

InitiateMultipartUploadResult result = storage.bucket("mybucket").object("blob").initiateMultipartUpload();

获得Multipart Upload Id

String uploadId = result.getUploadId();             

上传Part

storage.bucket("mybucket").object("blob").multipartUpload(uploadId).
    partNumber(1).
    entity(new File("/user/data/bin1")).
    upload();

复制Part

storage.bucket("mybucket").object("blob").multipartUpload(uploadId).
    partNumber(2).
    copySource("otherbucket", "bigdata").
    copySourceRange(255, 65335);
    copy();

完成Multipart Upload

storage.bucket("mybucket").object("blob").multipartUpload(uploadId).
    part(1, "ETag1").
    part(2, "ETag2").
    complete();

放弃Multipart Upload

storage.bucket("mybucket").object("blob").multipartUpload(uploadId).abort();

列出未完成的Parts

storage.bucket("mybucket").object("blob").multipartUpload(uploadId).
    partNumberMarker(10).
    maxParts(5).
    listParts();

Exception

盛大云存储SDK会将云存储服务返回的Error转换成统一的异常层次:SNDAServiceException,用户可以基于该类型来实现诸如错误处理与诊断等操作。

public class SNDAServiceException extends RuntimeException {

    public int status()             //获得错误代表的HTTP状态码(Status)

    public String getRequestId()    //获得请求的ID,当错误发生时,开发者可以将该ID记录下来并告知盛大云存储服务来快速诊断错误

    public DateTime getDate()       //获得异常发生的时间

    public String getCode()         //获得错误码,对应Error结构中的Code元素,HEAD请求时,该值为null

    public String getResource()     //获得错误对应的资源,对应Error结构中的Resource元素,HEAD请求时,该值为null

    public String getErrorMessage() //获得错误消息,对应Error结构中的Message元素,HEAD请求时,该值为null

}

除了标准的错误信息外,用户还可以获得额外的错误信息:

try {
    doSomething();
} catch (SNDAServiceException e) {
    if ("SignatureDoesNotMatch".equals(e.getCode()) {
        String signatureProvided = e.getError().get("SignatureProvided");
    }
}

依赖

盛大云存储SDK依赖以下的第三方库:

依赖 描述 网址
Google Guava Google提供的Java基础类库,提供了函数式编程,并发,集合操作等多种基础功能 http://code.google.com/p/guava-libraries/
Joda Time 一套关于时间的类库,已被收入至JDK 7中 http://joda-time.sourceforge.net/
SLF4J 功能强大的日志框架 http://www.slf4j.org/
Apache Commons-Lang 用来实现一些基础的操作,例如Object hashcode与equals方法的实现 http://commons.apache.org/lang/
Apache Commons-Codec 用来进行一些诸如Base64之类的编码算法 http://commons.apache.org/codec/
Apache HTTP Client 用来实现HTTP协议与网络数据的传输 http://hc.apache.org/httpclient-3.x/
Jackson 著名的JSON格式序列化工具,只有在使用Bucket Policy时需要 http://jackson.codehaus.org/

Copyright

Copyright (c) 2012 grandcloud.cn. All rights reserved.

Something went wrong with that request. Please try again.