diff --git a/CHANGELOG.md b/CHANGELOG.md index 944a8d78f..612205d28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,29 @@ ## CHANGE LOG +### v6.0.5 + +2013-10-08 issue [#82](https://github.com/qiniu/java-sdk/pull/82) + +- 增加私有资源fop的接口,包括exif,imageInfo,ImageView + ### v6.0.4 2013-09-02 issue [#78](https://github.com/qiniu/java-sdk/pull/78) -hot fix,增加EndUser字段至PutPolicy的JSON字符串中 +- 添加ListPrefix +- hot fix,增加EndUser字段至PutPolicy的JSON字符串中 ### v6.0.3 2013-08-5 issue [#76](https://github.com/qiniu/java-sdk/pull/76) -Bug fix,编码强制UTF-8修复 +- Bug fix,编码强制UTF-8修复 ### v6.0.1 2013-08-5 issue [#74](https://github.com/qiniu/java-sdk/pull/74) -Bug fix,增加PutPolicy类的 callbackBody字段到PutPolicy的Json格式中 +- Bug fix,增加PutPolicy类的 callbackBody字段到PutPolicy的Json格式中 ### v6.0.0 diff --git a/docs/README.md b/docs/README.md index 648107244..bc920b8ce 100644 --- a/docs/README.md +++ b/docs/README.md @@ -197,8 +197,8 @@ public class UploadFile { String uptoken = putPolicy.token(mac); PutExtra extra = new PutExtra(); String key = ""; - File file = new File(""); - PutRet ret = IoApi.put(uptoken, key, file, extra); + String localFile = ""; + PutRet ret = IoApi.putFile(uptoken, key, localFile, extra); } } @@ -217,7 +217,7 @@ public class UploadFile { [uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 实际上是用 AccessKey/SecretKey 进行数字签名的上传策略(`rs.PutPolicy`),它控制则整个上传流程的行为。让我们快速过一遍你都能够决策啥: * `expires` 指定 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 有效期(默认1小时)。一个 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 可以被用于多次上传(只要它还没有过期)。 -* `scope` 限定客户端的权限。如果 `scope` 是 bucket,则客户端只能新增文件到指定的 bucket,不能修改文件。如果 `scope` 为 bucket:key,则客户端可以修改指定的文件。 +* `scope` 限定客户端的权限。如果 `scope` 是 bucket,则客户端只能新增文件到指定的 bucket,不能修改文件。如果 `scope` 为 bucket:key,则客户端可以修改指定的文件。**注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误** * `callbackUrl` 设定业务服务器的回调地址,这样业务服务器才能感知到上传行为的发生。可选。 * `asyncOps` 可指定上传完成后,需要自动执行哪些数据处理。这是因为有些数据处理操作(比如音视频转码)比较慢,如果不进行预转可能第一次访问的时候效果不理想,预转可以很大程度改善这一点。 * `returnBody` 可调整返回给客户端的数据包(默认情况下七牛返回文件内容的 `hash`,也就是下载该文件时的 `etag`)。这只在没有 `CallbackUrl` 时有效。 @@ -242,7 +242,9 @@ public class UploadFile { [GET] http:/// -其中可以到[七牛云存储开发者自助网站](https://portal.qiniu.com)绑定, 域名可以使用自己一级域名的或者是由七牛提供的二级域名(`.qiniudn.com`)。注意,尖括号不是必需,代表替换项。 +其中\是bucket所对应的域名。七牛云存储为每一个bucket提供一个默认域名。默认域名可以到[七牛云存储开发者平台](https://portal.qiniu.com/)中,空间设置的域名设置一节查询。用户也可以将自有的域名绑定到bucket上,通过自有域名访问七牛云存储。 + +**注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误** @@ -674,8 +676,24 @@ public class ListPrefix { Config.ACCESS_KEY = ""; Config.SECRET_KEY = ""; Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY); + RSFClient client = new RSFClient(mac); - client.listPrifix("", "", "", 10); + String marker = ""; + + List all = new ArrayList(); + ListPrefixRet ret = null; + while (true) { + ret = client.listPrifix(bucketName, "", 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 + } } } ``` diff --git a/src/main/java/com/qiniu/api/fop/ImageExif.java b/src/main/java/com/qiniu/api/fop/ImageExif.java index 076c1772e..2362fcb00 100644 --- a/src/main/java/com/qiniu/api/fop/ImageExif.java +++ b/src/main/java/com/qiniu/api/fop/ImageExif.java @@ -2,8 +2,9 @@ import com.qiniu.api.net.CallRet; import com.qiniu.api.net.Client; - - +import com.qiniu.api.auth.AuthException; +import com.qiniu.api.auth.digest.*; +import com.qiniu.api.rs.*; public class ImageExif { /** @@ -22,5 +23,11 @@ public static ExifRet call(String url) { return new ExifRet(ret); } - + public static ExifRet call(String url,Mac mac) throws AuthException { + String pubUrl = makeRequest(url); + GetPolicy policy =new GetPolicy(); + String priUrl = policy.makeRequest(pubUrl, mac); + CallRet ret = new Client().call(priUrl); + return new ExifRet(ret); + } } diff --git a/src/main/java/com/qiniu/api/fop/ImageInfo.java b/src/main/java/com/qiniu/api/fop/ImageInfo.java index 6757b59e0..4a03bb0e4 100644 --- a/src/main/java/com/qiniu/api/fop/ImageInfo.java +++ b/src/main/java/com/qiniu/api/fop/ImageInfo.java @@ -1,8 +1,11 @@ package com.qiniu.api.fop; + import com.qiniu.api.net.CallRet; import com.qiniu.api.net.Client; - +import com.qiniu.api.auth.AuthException; +import com.qiniu.api.auth.digest.*; +import com.qiniu.api.rs.*; public class ImageInfo { /** @@ -20,4 +23,12 @@ public static ImageInfoRet call(String url) { CallRet ret = new Client().call(makeRequest(url)); return new ImageInfoRet(ret); } + + public static ImageInfoRet call(String url,Mac mac) throws AuthException { + String pubUrl = makeRequest(url); + GetPolicy policy =new GetPolicy(); + String priUrl = policy.makeRequest(pubUrl, mac); + CallRet ret = new Client().call(priUrl); + return new ImageInfoRet(ret); + } } diff --git a/src/main/java/com/qiniu/api/fop/ImageView.java b/src/main/java/com/qiniu/api/fop/ImageView.java index 45eefa687..e198bd72c 100644 --- a/src/main/java/com/qiniu/api/fop/ImageView.java +++ b/src/main/java/com/qiniu/api/fop/ImageView.java @@ -2,6 +2,10 @@ import com.qiniu.api.net.CallRet; import com.qiniu.api.net.Client; +import com.qiniu.api.rs.GetPolicy; +import com.qiniu.api.auth.AuthException; +import com.qiniu.api.auth.digest.*; +import com.qiniu.api.rs.*; public class ImageView { /** @@ -81,4 +85,12 @@ public CallRet call(String url) { CallRet ret = new Client().call(this.makeRequest(url)); return ret; } + + public CallRet call(String url,Mac mac) throws AuthException { + String pubUrl = makeRequest(url); + GetPolicy policy =new GetPolicy(); + String priUrl = policy.makeRequest(pubUrl, mac); + CallRet ret = new Client().call(priUrl); + return ret; + } } diff --git a/src/main/java/com/qiniu/api/rsf/ListItem.java b/src/main/java/com/qiniu/api/rsf/ListItem.java index 9a78890b5..c6a37249b 100644 --- a/src/main/java/com/qiniu/api/rsf/ListItem.java +++ b/src/main/java/com/qiniu/api/rsf/ListItem.java @@ -39,4 +39,16 @@ private void unmarshal(JSONObject jsonObject) throws JSONException { this.endUser = jsonObject.getString("endUser"); } } + + @Override + public String toString() { + StringBuilder sbuf = new StringBuilder(); + sbuf.append("key:").append(this.key); + sbuf.append(" hash:").append(this.hash); + sbuf.append(" fsize:").append(this.fsize); + sbuf.append(" putTime:").append(this.putTime); + sbuf.append(" mimeType:").append(this.mimeType); + sbuf.append(" endUser:").append(this.endUser); + return sbuf.toString(); + } } diff --git a/src/main/java/com/qiniu/api/rsf/RSFClient.java b/src/main/java/com/qiniu/api/rsf/RSFClient.java index 0688f59ef..fec02cb2a 100644 --- a/src/main/java/com/qiniu/api/rsf/RSFClient.java +++ b/src/main/java/com/qiniu/api/rsf/RSFClient.java @@ -19,7 +19,7 @@ public ListPrefixRet listPrifix(String bucketName, String prefix, String marker, if (marker != null && marker.length() != 0) { params.append("&marker=").append(marker); } - if (prefix != null && marker.length() != 0) { + if (prefix != null && prefix.length() != 0) { params.append("&prefix=").append(prefix); } if (limit > 0) { @@ -28,7 +28,11 @@ public ListPrefixRet listPrifix(String bucketName, String prefix, String marker, String url = Config.RSF_HOST + "/list?" + params.toString(); CallRet ret = conn.call(url); - return new ListPrefixRet(ret); + ListPrefixRet listRet = new ListPrefixRet(ret); + if (listRet.marker == null || "".equals(listRet.marker)) { + listRet.exception = new RSFEofException("EOF"); + } + return listRet; } } diff --git a/src/main/java/com/qiniu/api/rsf/RSFEofException.java b/src/main/java/com/qiniu/api/rsf/RSFEofException.java new file mode 100644 index 000000000..3f2d80027 --- /dev/null +++ b/src/main/java/com/qiniu/api/rsf/RSFEofException.java @@ -0,0 +1,22 @@ +package com.qiniu.api.rsf; + +public class RSFEofException extends Exception { + + private static final long serialVersionUID = 1L; + + protected RSFEofException() { + super(); + } + + public RSFEofException(String detailMessage) { + super(detailMessage); + } + + public RSFEofException(String detailMessage, Throwable throwable) { + super(detailMessage, throwable); + } + + public RSFEofException(Throwable throwable) { + super(throwable); + } +} diff --git a/src/test/java/com/qiniu/testing/AllCase.java b/src/test/java/com/qiniu/testing/AllCase.java index 5d3b76534..b029dbe7e 100644 --- a/src/test/java/com/qiniu/testing/AllCase.java +++ b/src/test/java/com/qiniu/testing/AllCase.java @@ -21,6 +21,7 @@ public static Test suite() { suite.addTestSuite(BatchCopyTest.class); suite.addTestSuite(BatchMoveTest.class); + suite.addTestSuite(RSFTest.class); return suite; } diff --git a/src/test/java/com/qiniu/testing/FileopTest.java b/src/test/java/com/qiniu/testing/FileopTest.java index 9a25daf43..caa219380 100644 --- a/src/test/java/com/qiniu/testing/FileopTest.java +++ b/src/test/java/com/qiniu/testing/FileopTest.java @@ -82,7 +82,7 @@ public void testImageExif() throws Exception { } public void testImageView() throws Exception { - String url = domain + "/" + key; + String url = "http://qiniuphotos.qiniudn.com/gogopher.jpg"; { ImageView iv = new ImageView(); iv.mode = 1; diff --git a/src/test/java/com/qiniu/testing/RSFTest.java b/src/test/java/com/qiniu/testing/RSFTest.java index 8df849083..4eb6ca9b1 100644 --- a/src/test/java/com/qiniu/testing/RSFTest.java +++ b/src/test/java/com/qiniu/testing/RSFTest.java @@ -1,6 +1,8 @@ package com.qiniu.testing; import java.io.File; +import java.util.ArrayList; +import java.util.List; import junit.framework.TestCase; @@ -9,18 +11,17 @@ import com.qiniu.api.io.IoApi; import com.qiniu.api.io.PutExtra; import com.qiniu.api.io.PutRet; -import com.qiniu.api.net.CallRet; -import com.qiniu.api.rs.Entry; import com.qiniu.api.rs.PutPolicy; -import com.qiniu.api.rs.RSClient; +import com.qiniu.api.rsf.ListItem; import com.qiniu.api.rsf.ListPrefixRet; import com.qiniu.api.rsf.RSFClient; +import com.qiniu.api.rsf.RSFEofException; public class RSFTest extends TestCase { // because all the testcase concurrently executes // so the key should be different. - public final String key = "RSFTest-key"; + public final String key = "_javasdk_RSFTest-key"; public final String expectedHash = "FmDZwqadA4-ib_15hYfQpb7UXUYR"; @@ -50,45 +51,45 @@ public void testRSF() throws Exception { PutExtra extra = new PutExtra(); - PutRet ret = IoApi - .putFile(uptoken, key, localFile, extra); - - assertTrue(ret.ok()); - assertTrue(expectedHash.equals(ret.getHash())); - + // upload 3 files + for (int i = 0; i < 3; i++) { + PutRet ret = IoApi.putFile(uptoken, key + "_" + i,localFile, extra); + assertTrue(ret.ok()); + assertTrue(expectedHash.equals(ret.getHash())); + } + } // we don't checkout the result of how may items are in the buckets. // not very convient, it's better, although. { RSFClient client = new RSFClient(mac); - ListPrefixRet ret = client.listPrifix(bucketName, "", "", 100); - assertTrue(ret.ok()); + String marker = ""; + + List all = new ArrayList(); + ListPrefixRet ret = null; + while (true) { + ret = client.listPrifix(bucketName, "_javasdk", 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 + System.out.println(ret.exception); + } + + // 防止该bucket有别人在用 + System.out.println(ret.exception); + System.out.println(all.size()); + assertTrue(all.size() >= 3); } } @Override public void tearDown() { - // delete the metadata from rs - // confirms it exists. - { - RSClient rs = new RSClient(mac); - Entry sr = rs.stat(bucketName, key); - assertTrue(sr.ok()); - assertTrue(expectedHash.equals(sr.getHash())); - } - - // deletes it from rs - { - RSClient rs = new RSClient(mac); - CallRet cr = rs.delete(bucketName, key); - assertTrue(cr.ok()); - } - - // confirms that it's deleted - { - RSClient rs = new RSClient(mac); - Entry sr = rs.stat(bucketName, key); - assertTrue(!sr.ok()); - } + // do nothing here. } } \ No newline at end of file