human: 如何处理七牛云的对象存储Java SDK 历史文档

gpt: [对象存储](https://developer.qiniu.com/kodo) > SDK 下载 > [Java
SDK](https://developer.qiniu.com/kodo/sdk/1239/java) > Java SDK 历史文档

#  Java SDK 历史文档

最近更新时间: 2017-01-23 10:21:38

此SDK适用于Java 6及以上版本。

  * [SDK下载地址](https://github.com/qiniu/java-sdk/tags)
  * [jar文件下载](http://search.maven.org/#search%7Cga%7C1%7Cqiniu)

# 安装

安装 Maven 的插件：[The Maven Integration for Eclipse](http://www.eclipse.org/m2e/)

添加依赖

    
    
    <dependency>
    	<groupId>com.qiniu</groupId>
    	<artifactId>qiniu-java-sdk</artifactId>
    	<version>[6.1.7, 6.999]</version>
    </dependency>
    

**配置密钥**

要接入七牛云存储，您需要拥有一对有效的 Access Key 和 Secret Key 用来进行签名认证。可以通过如下步骤获得：

  1. [开通七牛开发者帐号](https://portal.qiniu.com/signup)
  2. 登录七牛开发者自助平台，查看 [Access Key 和 Secret Key](https://portal.qiniu.com/user/key)

在获取到 Access Key 和 Secret Key 之后，您可以按照如下方式进行密钥配置：

    
    
    import com.qiniu.api.config.Config;
    
    public class Init {
    
    	public static void main(String[] args) {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    	}
    }
    

# 上传

为了尽可能地改善终端用户的上传体验，七牛云存储首创了客户端直传功能。

一般云存储的上传流程是：

    
    
    客户端（终端用户） => 业务服务器 => 云存储服务
    

这样通过用户自己的业务服务器中转上传至云存储服务端。这种方式存在一些不足：

  1. 多了一次中转的上传过程，同数据存放在用户的业务服务器中相比，会相对慢一些；
  2. 增加了用户业务服务器的负载，消耗了带宽，占用了磁盘，降低了服务能力；
  3. 增加了用户的流量消耗，来自终端用户的上传数据进入业务服务器，然后再次上传至云存储服务，净增一倍流量。

因此，七牛云存储引入了客户端直传的模式，将整个上传过程调整为：

    
    
    客户端（终端用户） => 七牛 => 业务服务器
    

客户端（终端用户）直接上传到七牛的服务器。通过DNS智能解析，七牛会选择到离终端用户最近的ISP服务商节点，速度会相比数据存放在用户自己的业务服务器上的方式更快。而且，七牛云存储可以在用户文件上传成功以后，替用户的客户端向用户的业务服务器发送反馈信息，减少用户的客户端同业务服务器之间的交互。详情请参考[上传策略](https://developer.qiniu.com/kodo/manual/put-
policy)

**注意** ：如果您只是想要将您电脑上，或者是服务器上的文件上传到七牛云存储，可以直接使用七牛提供的
[qshell](https://developer.qiniu.com/kodo/tools/qshell)上传工具，而无需额外开发。

文件上传有两种方式：普通方式，即一次性上传整个文件；断点续上传，即将文件分割成若干小块，分别上传，然后在七牛云存储服务端重新合并成一个文件。一般情况下，用户可以采用普通上传。如果文件较大，或者网络条件不佳，那么可以使用断点续上传，提高上传的速度和成功率。

## 上传流程

在七牛云存储中，整个上传流程大体分为这样几步：

  1. 业务服务器颁发上传凭证给客户端（终端用户）
  2. 客户端凭借上传凭证上传文件到七牛
  3. 在七牛获得完整数据后，根据用户请求的设定执行以下操作：

  * 如果用户设定了 returnUrl ，七牛云存储将反馈一个指向returnUrl的HTTP 303，驱动客户端执行跳转。
  * 如果用户设定了 callbackUrl] ，七牛云存储将向callbackUrl指定的地址发起一个HTTP 请求回调业务服务器，同时向业务服务器发送数据。发送的数据内容由 callbackBody 指定。业务服务器完成回调的处理后，可以在HTTP Response中放入数据，七牛云存储会响应客户端，并将业务服务器反馈的数据发送给客户端。 
    * 如果两者都没有设置，七牛云存储根据 returnBody 的设定向客户端发送反馈信息。

**注意：** 回调到业务服务器的过程是可选的，它取决于业务服务器颁发的上传凭证。

如果没有回调，七牛会返回一些标准的信息（比如文件的 hash）给客户端。如果上传发生在业务服务器，以上流程可以自然简化为：

  1. 业务服务器生成上传凭证 不设置回调，自己回调到自己这里没有意义）
  2. 凭借上传凭证上传文件到七牛
  3. 善后工作，比如保存相关的一些信息

## 生成上传授权uptoken

uptoken是一个字符串，作为http协议Header的一部分（Authorization字段）发送到我们七牛的服务端，表示这个http请求是经过用户授权的。

    
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rs.PutPolicy;
    
    public class Uptoken {
    
    	public static void main(String[] args) throws Exception {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		// 请确保该bucket已经存在
    		String bucketName = "Your bucket name";
    		PutPolicy putPolicy = new PutPolicy(bucketName);
    		String uptoken = putPolicy.token(mac);
    	}
    }
    

## 上传代码

上传本地文件。如果用户从自己的计算机或服务器上传文件，可以直接使用七牛云存储提供的 qrsync 工具。用户也可以自行编写上传程序。

上传程序大体步骤如下：

  1. 设置AccessKey和SecretKey；
  2. 创建Mac对象；
  3. 创建PutPolicy对象；
  4. 生成UploadToken；
  5. 创建PutExtra对象；
  6. 调用put或putFile方法上传文件；

具体代码如下：

    
    
    import java.io.File;
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.io.IoApi;
    import com.qiniu.api.io.PutExtra;
    import com.qiniu.api.io.PutRet;
    import com.qiniu.api.rs.PutPolicy;
    
    public class UploadFile {
    	
    	public static void main(String[] args) throws Exception {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		// 请确保该bucket已经存在
    		String bucketName = "<Your bucket name>";
    		PutPolicy putPolicy = new PutPolicy(bucketName);
    		String uptoken = putPolicy.token(mac);
    		PutExtra extra = new PutExtra();
    		String key = "<key>";
    		String localFile = "<local file path>";
    		PutRet ret = IoApi.putFile(uptoken, key, localFile, extra);
    	}
    }
    

## 断点续上传、分块并行上传

与普通上传类似：

    
    
    private void uploadFile() throws AuthException, JSONException{
    		PutPolicy p = new PutPolicy(bucketName);
    		p.returnBody = "{\"key\": $(key), \"hash\": $(etag),\"mimeType\": $(mimeType)}";
    		String upToken = p.token(mac);
    		PutRet ret = ResumeableIoApi.put(file, upToken, key, mimeType);
    	}
    	
    	private void uploadStream() throws AuthException, JSONException, FileNotFoundException{
    		PutPolicy p = new PutPolicy(bucketName);
    		String upToken = p.token(mac);
    		FileInputStream fis = new FileInputStream(file);
    		PutRet ret = ResumeableIoApi.put(fis, upToken, key, mimeType);
    	}
    

key，mimeType 可为null。

## 上传策略

uptoken实际上是用 AccessKey/SecretKey
进行数字签名的上传策略(`rs.PutPolicy`)，它控制则整个上传流程的行为。让我们快速过一遍你都能够决策啥：

  * `expires` 指定 uptoken 有效时长。单位：秒（s），默认1小时，3600秒。deadline = System.currentTimeMillis() / 1000 + this.expires，不直接指定deadline。一个 uptoken 可以被用于多次上传（只要它还没有过期）。

关于上传策略更完整的说明，请参考 [uptoken](https://developer.qiniu.com/kodo/manual/upload-
token)。

# 文件下载

七牛云存储上的资源下载分为 公有资源下载 和 私有资源下载 。

私有（private）是 Bucket（空间）的一个属性，一个私有 Bucket 中的资源为私有资源，私有资源不可匿名下载。

新创建的空间（Bucket）缺省为私有，也可以将某个 Bucket 设为公有，公有 Bucket 中的资源为公有资源，公有资源可以匿名下载。

## 公有资源下载

如果在给bucket绑定了域名的话，可以通过以下地址访问。

    
    
    [GET] http://<domain>/<key>
    

其中<domain>是bucket所对应的域名。七牛云存储为每一个bucket提供一个默认域名。默认域名可以到[七牛开发者平台](https://portal.qiniu.com/)中，空间设置的域名设置一节查询。用户也可以将自有的域名绑定到bucket上，通过自有域名访问七牛云存储。

**注意：** key必须采用utf8编码，如使用非utf8编码访问七牛云存储将反馈错误

## 私有资源下载

私有资源必须通过临时下载授权凭证(downloadToken)下载，如下：

    
    
    [GET] http://<domain>/<key>?token=<downloadToken>
    

注意，尖括号不是必需，代表替换项。

`downloadToken` 可以使用 SDK 提供的如下方法生成：

    
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rs.GetPolicy;
    import com.qiniu.api.rs.URLUtils;
    
    public class DownloadFile {
    
    	public static void main(String[] args) throws Exception {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		String baseUrl = URLUtils.makeBaseUrl("<domain>", "<key>");
    		GetPolicy getPolicy = new GetPolicy();
    		String downloadUrl = getPolicy.makeRequest(baseUrl, mac);
    	}
    }
    

# 资源管理接口

文件管理包括对存储在七牛云存储上的文件进行查看、复制、移动和删除处理。

## 查看单个文件属性信息

    
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rs.Entry;
    import com.qiniu.api.rs.RSClient;
    
    public class Stat {
    
    	public static void main(String[] args) {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		RSClient client = new RSClient(mac);
    		Entry statRet = client.stat("<bucketName>", "<key>");
    	}
    }
    

## 复制单个文件

    
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rs.RSClient;
    
    public class Copy {
    
    	public static void main(String[] args) {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		RSClient client = new RSClient(mac);
    		client.copy("<bucketSrc>", "<keySrc>", "<bucketDest>", "<keyDest>");
    	}
    }
    

## 移动单个文件

    
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rs.RSClient;
    
    public class Move {
    
    	public static void main(String[] args) {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		RSClient client = new RSClient(mac);
    		client.move("<bucketSrc>", "<keySrc>", "<bucketDest>", "<keyDest>");
    	}
    }
    
    

## 删除单个文件

    
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rs.RSClient;
    
    public class Delete {
    
    	public static void main(String[] args) {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		RSClient client = new RSClient(mac);
    		client.delete("<bucketName>", "<key>");
    	}
    }
    

## 批量操作

当您需要一次性进行多个操作时, 可以使用批量操作.

**批量获取文件属性信息**

    
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rs.BatchStatRet;
    import com.qiniu.api.rs.EntryPath;
    import com.qiniu.api.rs.RSClient;
    
    public class BatchStat {
    
    	public static void main(String[] args) {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		
    		RSClient rs = new RSClient(mac);
    		List<EntryPath> entries = new ArrayList<EntryPath>();
    
    		EntryPath e1 = new EntryPath();
    		e1.bucket = "<bucketName>";
    		e1.key = "<key1>";
    		entries.add(e1);
    
    		EntryPath e2 = new EntryPath();
    		e2.bucket = "<bucketName>";
    		e2.key = "<key2>";
    		entries.add(e2);
    
    		BatchStatRet bsRet = rs.batchStat(entries);
    	}
    }
    

**批量复制文件**

    
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rs.BatchCallRet;
    import com.qiniu.api.rs.EntryPath;
    import com.qiniu.api.rs.EntryPathPair;
    import com.qiniu.api.rs.RSClient;
    
    public class BatchCopy {
    
    	public static void main(String[] args) {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		RSClient rs = new RSClient(mac);
    		List<EntryPathPair> entries = new ArrayList<EntryPathPair>();
    
    		EntryPathPair pair1 = new EntryPathPair();
    
    		EntryPath src = new EntryPath();
    		src.bucket = "<srcBucket>";
    		src.key = "<key1>";
    
    		EntryPath dest = new EntryPath();
    		dest.bucket = "<destBucket>";
    		dest.key = "<key1>";
    
    		pair1.src = src;
    		pair1.dest = dest;
    
    		EntryPathPair pair2 = new EntryPathPair();
    
    		EntryPath src2 = new EntryPath();
    		src2.bucket = "<srcBucket>";
    		src2.key = "<key2>";
    
    		EntryPath dest2 = new EntryPath();
    		dest2.bucket = "<destBucket>";
    		dest2.key = "<key2>";
    
    		pair2.src = src2;
    		pair2.dest = dest2;
    
    		entries.add(pair1);
    		entries.add(pair2);
    
    		BatchCallRet ret = rs.batchCopy(entries);
    	}
    }
    

**批量移动文件**

    
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rs.BatchCallRet;
    import com.qiniu.api.rs.EntryPath;
    import com.qiniu.api.rs.EntryPathPair;
    import com.qiniu.api.rs.RSClient;
    
    public class BatchMove {
    
    	public static void main(String[] args) {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		RSClient rs = new RSClient(mac);
    		List<EntryPathPair> entries = new ArrayList<EntryPathPair>();
    		
    		EntryPathPair pair1 = new EntryPathPair();
    		
    		EntryPath src = new EntryPath();
    		src.bucket = "<srcBucket>";
    		src.key = "<key1>";
    		
    		EntryPath dest = new EntryPath();
    		dest.bucket = "<destBucket>";
    		dest.key = "<key1>";
    		
    		pair1.src = src;
    		pair1.dest = dest;
    		
    		EntryPathPair pair2 = new EntryPathPair();
    		
    		EntryPath src2 = new EntryPath();
    		src2.bucket = "<srcBucket>";
    		src2.key =  "<key2>";
    		
    		EntryPath dest2 = new EntryPath();
    		dest2.bucket = "<destBucket>";
    		dest2.key = "<key2>";
    		
    		pair2.src = src2;
    		pair2.dest = dest2;
    		
    		entries.add(pair1);
    		entries.add(pair2);
    		
    		BatchCallRet ret = rs.batchMove(entries);
    	}
    }   
    

**批量删除文件**

    
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rs.BatchCallRet;
    import com.qiniu.api.rs.EntryPath;
    import com.qiniu.api.rs.RSClient;
    
    public class BatchDelete {
    
    	public static void main(String[] args) {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		RSClient rs = new RSClient(mac);
    		List<EntryPath> entries = new ArrayList<EntryPath>();
    
    		EntryPath e1 = new EntryPath();
    		e1.bucket = "<bucketName>";
    		e1.key = "<key1>";
    		entries.add(e1);
    
    		EntryPath e2 = new EntryPath();
    		e2.bucket = "<bucketName>";
    		e2.key = "<key2>";
    		entries.add(e2);
    
    		BatchCallRet bret = rs.batchDelete(entries);
    	}
    }
    
    

参阅: `rs.EntryPath`, `rs.Client.BatchDelete`

## 高级批量操作

批量操作不仅仅支持同时进行多个相同类型的操作, 同时也支持不同的操作.

    
    
    to do!
    

# 数据处理接口

七牛支持在云端对图像, 视频, 音频等富媒体进行个性化处理

## 图像

**查看图像属性**

    
    
    import com.qiniu.api.fop.ImageInfo;
    import com.qiniu.api.fop.ImageInfoRet;
    
    public class FopImageInfo {
    
    	public static void main(String[] args) {
    		String url = "<domain>" + "/" + "<key>";
    		ImageInfoRet ret = ImageInfo.call(url);
    	}
    }
    

参阅: `fop.ImageInfoRet`, `fop.ImageInfo`

**查看图片EXIF信息**

    
    
    import com.qiniu.api.fop.ExifRet;
    import com.qiniu.api.fop.ImageExif;
    
    public class FopImageExif {
    
    	public static void main(String[] args) {
    		String url = "<domain>" + "/" + "<key>";
    		ExifRet ret = ImageExif.call(url);
    	}
    }
    

**生成图片预览**

    
    
    import com.qiniu.api.fop.ImageView;
    import com.qiniu.api.net.CallRet;
    
    public class FopImageView {
    
    	public static void main(String[] args) {
    		String url = "http://domain/key";
    		ImageView iv = new ImageView();
    		iv.mode = 1 ;
    		iv.width = 100 ;
    		iv.height = 200 ;
    		iv.quality = 1 ;
    		iv.format = "jpg" ;
    		CallRet ret = iv.call(url);
    	}
    }
    

# 高级资源管理接口 (rsf)

## 批量获取文件列表

    
    
    import com.qiniu.api.auth.digest.Mac;
    import com.qiniu.api.config.Config;
    import com.qiniu.api.rsf.RSFClient;
    
    public class ListPrefix {
    
    	public static void main(String[] args) {
    		Config.ACCESS_KEY = "<YOUR APP ACCESS_KEY>";
    		Config.SECRET_KEY = "<YOUR APP SECRET_KEY>";
    		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
    		
    		RSFClient client = new RSFClient(mac);
    		String marker = "";
    			
    		List<ListItem> all = new ArrayList<ListItem>();
    		ListPrefixRet ret = null;
    		while (true) {
    			ret = client.listPrifix(bucketName, "<prifix>", marker, 10);
    			marker = ret.marker;
    			all.addAll(ret.results);
    			if (!ret.ok()) {
    				// no more items or error occurs
    				break;
    			}
    		}
    		if (ret.exception.getClass() != RSFEofException.class) {
    			// error handler
    		} 
    	}
    }
    

# 贡献代码

  1. Fork

  2. 创建您的特性分支 git checkout -b my-new-feature

  3. 提交您的改动 git commit -am ‘Added some feature’

  4. 将您的修改记录提交到远程 git 仓库 git push origin my-new-feature

  5. 然后到 github 网站的该 git 远程仓库的 my-new-feature 分支下发起 Pull Request

# 许可证

Copyright © 2014 qiniu.com

基于 MIT 协议发布:

  * [www.opensource.org/licenses/MIT](http://www.opensource.org/licenses/MIT)

以上内容是否对您有帮助？