diff --git a/CHANGELOG.md b/CHANGELOG.md index 612205d28..db67ce176 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ ## CHANGE LOG +### v6.1.0 + +2014-1-13 [#93](https://github.com/qiniu/java-sdk/pull/93) + +- bugfix: PutExtra.mimeType 不生效问题 +- PutPolicy 补充字段 + +### v6.0.7 + +2013-11-7 [#85](https://github.com/qiniu/java-sdk/pull/85) + +- PutPolicy增加持久化字段 + +### v6.0.6 + +2013-11-5 [#84](https://github.com/qiniu/java-sdk/pull/84) + +- 修复PutPolicy生成Token时,Expires改变的BUG + ### v6.0.5 2013-10-08 issue [#82](https://github.com/qiniu/java-sdk/pull/82) diff --git a/docs/README.md b/docs/README.md index bc920b8ce..c62b92da9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,6 +2,7 @@ title: Java SDK --- +# Java SDK 使用指南 此SDK适用于Java 6及以上版本。基于 [七牛云存储官方API](http://docs.qiniu.com) 构建。使用此 SDK 构建您的网络应用程序,能让您以非常便捷地方式将数据安全地存储到七牛云存储上。无论您的网络应用是一个网站程序,还是包括从云端(服务端程序)到终端(手持设备应用)的架构的服务或应用,通过七牛云存储及其 SDK,都能让您应用程序的终端用户高速上传和下载,同时也让您的服务端更加轻盈。 diff --git a/src/main/java/com/qiniu/api/io/IoApi.java b/src/main/java/com/qiniu/api/io/IoApi.java index 629c9cebf..181b37402 100644 --- a/src/main/java/com/qiniu/api/io/IoApi.java +++ b/src/main/java/com/qiniu/api/io/IoApi.java @@ -1,24 +1,26 @@ package com.qiniu.api.io; import java.io.File; -import java.io.InputStream; import java.io.FileInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.zip.CRC32; import java.util.zip.CheckedInputStream; import org.apache.http.entity.mime.MultipartEntity; +import org.apache.http.entity.mime.content.AbstractContentBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.InputStreamBody; import org.apache.http.entity.mime.content.StringBody; + import com.qiniu.api.config.Config; import com.qiniu.api.net.CallRet; import com.qiniu.api.net.Client; -import java.nio.charset.Charset; - public class IoApi { - public static final String UNDEFINED_KEY = "?"; + public static final String UNDEFINED_KEY = null; public static final int NO_CRC32 = 0; public static final int AUTO_CRC32 = 1; public static final int WITH_CRC32 = 2; @@ -30,15 +32,12 @@ private static PutRet put(String uptoken, String key, File file, return new PutRet(new CallRet(400, new Exception( "File does not exist or not readable."))); } - if (key == null) { - key = UNDEFINED_KEY; - } MultipartEntity requestEntity = new MultipartEntity(); try { requestEntity.addPart("token", new StringBody(uptoken)); - FileBody fileBody = new FileBody(file); + AbstractContentBody fileBody = buildFileBody(file, extra); requestEntity.addPart("file", fileBody); - requestEntity.addPart("key", new StringBody(key,Charset.forName("utf-8"))); + setKey(requestEntity, key); if (extra.checkCrc != NO_CRC32) { if (extra.crc32 == 0) { return new PutRet(new CallRet(400, new Exception("no crc32 specified!"))); @@ -55,13 +54,27 @@ private static PutRet put(String uptoken, String key, File file, return new PutRet(ret); } + private static FileBody buildFileBody(File file,PutExtra extra){ + if(extra.mimeType != null){ + return new FileBody(file, extra.mimeType); + }else{ + return new FileBody(file); + } + } + + private static void setKey(MultipartEntity requestEntity, String key) throws UnsupportedEncodingException{ + if(key != null){ + requestEntity.addPart("key", new StringBody(key,Charset.forName("utf-8"))); + } + } + private static PutRet putStream(String uptoken, String key, InputStream reader,PutExtra extra) { MultipartEntity requestEntity = new MultipartEntity(); try { requestEntity.addPart("token", new StringBody(uptoken)); - InputStreamBody inputBody= new InputStreamBody(reader,key); + AbstractContentBody inputBody = buildInputStreamBody(reader, extra, key); requestEntity.addPart("file", inputBody); - requestEntity.addPart("key", new StringBody(key,Charset.forName("utf-8"))); + setKey(requestEntity, key); if (extra.checkCrc != NO_CRC32) { if (extra.crc32 == 0) { return new PutRet(new CallRet(400, new Exception("no crc32 specified!"))); @@ -78,12 +91,17 @@ private static PutRet putStream(String uptoken, String key, InputStream reader,P return new PutRet(ret); } + private static InputStreamBody buildInputStreamBody(InputStream reader,PutExtra extra, String key){ + if(extra.mimeType != null){ + return new InputStreamBody(reader, extra.mimeType, key); + }else{ + return new InputStreamBody(reader, key); + } + } + public static PutRet Put(String uptoken,String key,InputStream reader,PutExtra extra) { - if (key == null) { - key = UNDEFINED_KEY; - } PutRet ret = putStream(uptoken,key,reader,extra); return ret; } diff --git a/src/main/java/com/qiniu/api/net/EncodeUtils.java b/src/main/java/com/qiniu/api/net/EncodeUtils.java index c40225d2f..ff1eee099 100644 --- a/src/main/java/com/qiniu/api/net/EncodeUtils.java +++ b/src/main/java/com/qiniu/api/net/EncodeUtils.java @@ -36,7 +36,19 @@ public static byte[] urlsafeEncodeBytes(byte[] src) { } return b2; } - + + public static byte[] urlsafeBase64Decode(String encoded){ + byte[] rawbs = encoded.getBytes(); + for(int i=0;i 0) { stringer.key("asyncOps").value(this.asyncOps); } + if (this.saveKey != null && this.saveKey.length() > 0) { + stringer.key("saveKey").value(this.saveKey); + } + if(this.insertOnly>0){ + stringer.key("insertOnly").value(this.insertOnly); + } + if(this.detectMime>0){ + stringer.key("detectMime").value(this.detectMime); + } + if(this.fsizeLimit>0){ + stringer.key("fsizeLimit").value(this.fsizeLimit); + } if (this.endUser != null && this.endUser.length() > 0) { stringer.key("endUser").value(this.endUser); } - stringer.key("deadline").value(this.expires); + if (this.persistentNotifyUrl != null && this.persistentNotifyUrl.length() > 0) { + stringer.key("persistentNotifyUrl").value(this.persistentNotifyUrl); + } + if (this.persistentOps != null && this.persistentOps.length() > 0) { + stringer.key("persistentOps").value(this.persistentOps); + } + stringer.key("deadline").value(this.deadline); stringer.endObject(); return stringer.toString(); @@ -78,7 +110,7 @@ public String token(Mac mac) throws AuthException, JSONException { if (this.expires == 0) { this.expires = 3600; // 3600s, default. } - this.expires = System.currentTimeMillis() / 1000 + expires; + this.deadline = System.currentTimeMillis() / 1000 + this.expires; byte[] data = this.marshal().getBytes(); return DigestAuth.signWithData(mac, data); } diff --git a/src/test/java/com/qiniu/testing/UtilTest.java b/src/test/java/com/qiniu/testing/UtilTest.java new file mode 100644 index 000000000..86069aaf1 --- /dev/null +++ b/src/test/java/com/qiniu/testing/UtilTest.java @@ -0,0 +1,23 @@ +package com.qiniu.testing; + + +import junit.framework.TestCase; + +import com.qiniu.api.net.EncodeUtils; + +public class UtilTest extends TestCase { + + // just upload an image in testdata. + public void test() throws Exception { + String expectString = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+}{:?><-=,./;'[]"; + String encodedString = "MTIzNDU2Nzg5MGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVp-IUAjJCVeJiooKV8rfXs6Pz48LT0sLi87J1td"; + byte[] rawBytes = EncodeUtils.urlsafeBase64Decode(encodedString); + String decoded = new String(rawBytes); + assertTrue(expectString.equals(decoded)); + } + + @Override + public void tearDown() { + // do nothing here. + } +}