JetS3t使用说明


JetS3t 使用说明 http://ywskycn.com 1. JetS3t 简介 JetS3t 1 是一个用于与 Amazon Simple Storage Service 2 (Amazon S3)和 Amazon CloudFront3交互的 Java 开源工具箱。它将 Amazon S3 的一些 API 抽象成常见的 Java 方法和 类,方便开发人员更好的与 S3 进行交互。JetS3t 开发套件中包括 5 个主要的应用程序: ¾ Cockpit:一个 GUI 工具用户传输文件,查看和管理 Amazon S3 帐号中的内容。 ¾ Synchronize:用于同步用户计算机上的目录和 Amazon S3 账户的命令行工具,最 适合于不同的计算机之间同步文件与备份。 ¾ Gatekeeper:一个 Servlet 可以作为访问 Amazon S3 账户的中介,其它没有 S3 账户 的客户端可以利用这个 Servlet 实现上传,下载,删除等操作。 ¾ CockpitLite:Cockpit 的简约版本,它通过中介 Gatekeeper 服务实现所有操作。 ¾ Uploader:一 个 GUI 应用程序,提供一个通过 Gatekeeper 服务实现文件上传的简单 向导。 这 5 个应用程序都是基于 JetS3t 工具箱开发,展示了如何利用该工具箱做进一步的开发。 JetS3t 采用 Apache License,Version 2.0 开源协议。 2. 代码示例 本节主要介绍有关于 JetS3t 的简单实例代码。JetS3t 依赖以下类库: Library URL HttpClient 3.1 http://jakarta.apache.org/commons/httpclient/ Log4J http://logging.apache.org/log4j/docs/ Bare Bones Browser Launcher http://www.centerkey.com/java/browser/ Nuvola Icon Library http://icon-king.com/ Java Uuid Generator (JUG) http://jug.safehaus.org/Home Apache Axis 1.4 http://ws.apache.org/axis/ Bouncy Castle Crypto APIs http://www.bouncycastle.org/ Java XMLBuilder http://code.google.com/p/java-xmlbuilder/ 1 http://jets3t.s3.amazonaws.com/index.html 2 http://www.amazon.com/s3 3 http://www.amazon.com/cloudfront 2.1 基本操作 2.1.1 Connecting to S3 使用 JetS3t 对 S3 进行任何操作都需要提供 S3 账户的 awsAccessKey 和 awsSecretKey。 有关于这两个 Keys 的获取如下图所示: 由于 S3 只有两种存储结构,Bucket 和 Object。相对应 JetS3t 中的对象为: ¾ S3Bucket:S3 中的 Object 都存在某个 Bucket 之中,每个 Bucket 在 S3 中都有唯一 的名字。 ¾ S3Object:S3 的 Bucket 中的存储数据类型,每个 Object 都有一个 key 值。 连接到 S3 的实例代码如下: String awsAccessKey = “YOUR_AWS_ACCESS_KEY”; String awsSecreyKey = “YOUR_AWS_SECREY_KEY”; AWSCredentials awsCredentials = new AWSCredentials(awsAccessKey, awsSecretKey); 为了与 S3 交互,需要创建一个 S3Service 的对象。这里采用的 REST/HTTP 协议,这也 是 JetS3t 提供的最可靠的协议。 S3Service s3Service = new RestS3Service(awsCredentials); // list all the buckets S3Bucket myBuckets[] = s3Service.listAllBuckets(); System.our.println(“How many buckets do I have in S3?” + myBuckets.length); 2.1.2 Create a Bucket 为了将 Object 存储到 S3 中,首先需要创建一个 bucket,即创建 object 的容器。 S3Bucket testBucket = s3Service.createBucket("test-bucket"); System.out.println("Created test bucket: " + testBucket.getName()); 因为 bucket 的名字是 S3 全局唯一的,因此这里的“test-bucket”需要换成一个与其它 buckets 不重复的名字。在创建 bucket 时可以设置 location 参数,用来表示希望将该 bucket 存储在哪个地区的数据中心,例如下面的例子就是将 bucket 存储在 Amazon 设在欧洲的数 据中心。 S3Bucket euBucket = s3Service.createBucket("eu-bucket", S3Bucket.LOCATION_EUROPE); 这里可选的 location 有:US, US_STANDARD, US_WEST, 和 EUROPE。 2.1.3 Uploading Data/Files JetS3t 将 S3 中的 object 封装成 S3Object,因此在将数据上传到 S3 之前,我们需要创建 一个 S3Object(并用 key/name 标识),并通过 S3Service 上传到相应的 bucket 中。下面的代 码创建了一个 S3Object 对象,并将上传前和上传后的对象信息打印出来。上传之后的对象 会增加一些额外的信息,例如文件的最后修改时间等。 // Create an empty object with a key/name, and print the object's details. S3Object object = new S3Object("object"); System.out.println("S3Object before upload: " + object); // Upload the object to our test bucket in S3. object = s3Service.putObject(testBucket, object); // Print the details about the uploaded object, which contains more information. System.out.println("S3Object after upload: " + object); 上面的代码创建了一个名为“object”的空对象。当然,如果知道数据的 Content/Mime 类型(例如 text/plain),也可以设置 object 相应的数据内容。S3Object 不支持从输入流直接 获取数据信息,但是 JetS3t 提供了两类方法用来获取文件或字符串数据信息。相应的构造方 法会自动的设置 object 的 Content-Type 和 Content-Length 的信息。 // Create an S3Object based on a string, with Content-Length set automatically and // Content-Type set to "text/plain" String stringData = "Hello World!"; S3Object stringObject = new S3Object("HelloWorld.txt", stringData); // Create an S3Object based on a file, with Content-Length set automatically and // Content-Type set based on the file's extension (using the Mimetypes utility class) File fileData = new File("src/org/jets3t/samples/CodeSamples.java"); S3Object fileObject = new S3Object(fileData); 如果上传的数据既不是文件也不是字符串,那么可以通过输入流来实现数据上传,但是 需要手工设置 Content-Length 信息。 // Create an object containing a greeting string as input stream data. String greeting = "Hello World!"; S3Object helloWorldObject = new S3Object("HelloWorld2.txt"); ByteArrayInputStream greetingIS = new ByteArrayInputStream(greeting.getBytes()); helloWorldObject.setDataInputStream(greetingIS); helloWorldObject.setContentLength(greetingIS.available()); helloWorldObject.setContentType("text/plain"); // Upload the data objects. s3Service.putObject(testBucket, stringObject); s3Service.putObject(testBucket, fileObject); s3Service.putObject(testBucket, helloWorldObject); // Print details about the uploaded object. System.out.println("S3Object with data: " + helloWorldObject); 为了确保在传输过程中不出现异常问题,我们需要检查 S3 接收到的数据的哈希值与本 地原始文件的哈希值是否匹配。实现该机制的一个简单的方法就是在上传数据之前,设置 object 的 Content-MD5 值。当你使用 File-或 String-based 的 S3Object 构造方法时,JetS3t 将 会自动设置 Content-MD5 的值。 S3Object objectWithHash = new S3Object(testBucket, "HelloWorld.txt", stringData); System.out.println("Hash value: " + objectWithHash.getMd5HashAsHex()); 当你使用的不是这类构造方法时,那么需要手工设置 Content-MD5 值。JetS3t 提供相应 的方法来计算一个输入流或者字节流的相应的哈希值。 ByteArrayInputStream dataIS = new ByteArrayInputStream( "Here is my data".getBytes(Constants.DEFAULT_ENCODING)); byte[] md5Hash = ServiceUtils.computeMD5Hash(dataIS); dataIS.reset(); stringObject = new S3Object("MyData"); stringObject.setDataInputStream(dataIS); stringObject.setMd5Hash(md5Hash); 2.1.4 Downloading Objects 如果只是希望了解 S3 账户中某个文件的一些信息(即 HEAD 信息),那么不需要下载 整个 object。这里的 HEAD 信息包括 object 的大小,时间,Content Type 等等。 // Retrieve the HEAD of the data object we created previously. S3Object objectDetailsOnly = s3Service.getObjectDetails(testBucket, "helloWorld.txt"); System.out.println("S3Object, details only: " + objectDetailsOnly); 如果希望获取 object 的内容信息,可以通过下列代码实现: // Retrieve the whole data object we created previously S3Object objectComplete = s3Service.getObject(testBucket, "helloWorld.txt"); System.out.println("S3Object, complete: " + objectComplete); // Read the data from the object's DataInputStream using a loop, and print it out. System.out.println("Greeting:"); BufferedReader reader = new BufferedReader( new InputStreamReader(objectComplete.getDataInputStream())); String data = null; while ((data = reader.readLine()) != null) { System.out.println(data); } 同上传数据相同,如果需要判断下载过程中是否出现异常,通过检查 object 的哈希值即 可。 S3Object downloadedObject = s3Service.getObject(testBucket, "helloWorld.txt"); String textData = ServiceUtils.readInputStreamToString( downloadedObject.getDataInputStream(), "UTF-8"); boolean valid = downloadedObject.verifyData(textData.getBytes("UTF-8")); System.out.println("Object verified? " + valid); 2.1.5 Listing Your Buckets/Objects 通过上面的代码,我们 S3 的账户中现在已经有了一个 bucket,并且包含了一些 objects。 我们可以罗列出所有 bucket 和 object 的信息。需要说明的是,罗列出的 object 信息要少于方 法 getObject 和 getObjectDetails 返回的 object 信息。 // List all your buckets. S3Bucket[] buckets = s3Service.listAllBuckets(); // List the object contents of each bucket. for (int b = 0; b < buckets.length; b++) { System.out.println("Bucket '" + buckets[b].getName() + "' contains:"); // List the objects in this bucket. S3Object[] objects = s3Service.listObjects(buckets[b]); // Print out each object's key and size. for (int o = 0; o < objects.length; o++) { System.out.println(" " + objects[o].getKey() + " (" + objects[o].getContentLength() + " bytes)"); } } 当用户希望获取一个 bucket 中某一类对象的信息时,这种方法非常适用,因为它不需 要下载所有 object 的内容。 // List only objects whose keys match a prefix. String prefix = "Reports"; String delimiter = null; // Refer to the S3 guide for more information on delimiters S3Object[] filteredObjects = s3Service.listObjects(testBucket, prefix, delimiter); 2.1.6 Deleting Buckets/Objects Object 可以很容易被删除,而 Bucket 只有其为空时才可被删除。 // If you try to delete your bucket before it is empty, it will fail. try { // This will fail if the bucket isn't empty. s3Service.deleteBucket(testBucket.getName()); } catch (S3ServiceException e) { e.printStackTrace(); } // Delete all the objects in the bucket s3Service.deleteObject(testBucket, object.getKey()); s3Service.deleteObject(testBucket, helloWorldObject.getKey()); // Now that the bucket is empty, you can delete it. s3Service.deleteBucket(testBucket.getName()); System.out.println("Deleted bucket " + testBucket.getName()); 2.1.7 Copying Objects 可以在 Bucket 内部以及不同的 bucket 之间实现 object 的拷贝。 // Create a target S3Object S3Object targetObject = new S3Object("targetObjectWithSourcesMetadata"); boolean replaceMetadata = false; s3Service.copyObject("test-bucket", "HelloWorld.txt", "destination-bucket", targetObject, replaceMetadata); 也可以在拷贝对象的同时更新相应的 metadata 信息。 targetObject = new S3Object("HelloWorld.txt"); targetObject.addMetadata(S3Object.METADATA_HEADER_CONTENT_TYPE, "text/html"); replaceMetadata = true; s3Service.copyObject("test-bucket", "HelloWorld.txt", "test-bucket", targetObject, replaceMetadata); 2.1.8 Moving and Renaming Objects 可以在同一地区的数据中心中将 object 从一个 bucket 移动到另外一个 bucket 中。一个 文件移动操作由拷贝和删除操作组成。若拷贝操作失败,那么这个 object 不会被删除。但是 如果最终的删除操作失效,那么这个 object 将会在源 bucket 和目的 bucket 中都出现。 s3Service.moveObject("test-bucket", "HelloWorld.txt", "destination-bucket", targetObject, false); // You can move an object to a new name in the same bucket. This is essentially a rename operation. s3Service.moveObject("test-bucket", "HelloWorld.txt", "test-bucket", new S3Object("NewName.txt"), false); // To make renaming easier, JetS3t has a shortcut method especially for this purpose. s3Service.renameObject("test-bucket", "HelloWorld.txt", targetObject); 2.1.9 Bucket Versioning S3 的 bucket 提供 versioning 特性,允许 object 在被更新或删除的时候保存之前的版本。 这个特性也使得用户不用去担心一些重要的数据因为意外的覆盖或删除操作而丢失。在默认 设置中,S3 并没有开启 versioning 功能,需要用户手工开启该功能。而一旦开启该功能,用 户可以通过唯一的版本标识来访问管理某一版本的 object 数据。 // Create a bucket to test versioning S3Bucket versioningBucket = s3Service.getOrCreateBucket("test-versioning"); String vBucketName = versioningBucket.getName(); // Check bucket versioning status for the bucket S3BucketVersioningStatus versioningStatus = s3Service.getBucketVersioningStatus(vBucketName); System.out.println("Versioning enabled ? " + versioningStatus.isVersioningEnabled()); // Suspend (disable) versioning for a bucket -- will have no effect if bucket versioning is not yet // enabled. This will not delete any existing object versions. s3Service.suspendBucketVersioning(vBucketName); // Enable versioning for a bucket. s3Service.enableBucketVersioning(vBucketName); // Once versioning is enabled you can GET, PUT, copy and delete objects as normal. Every change to // an object will cause a new version to be created. // Store and update and delete an object in the versioning bucket S3Object versionedObject = new S3Object("versioned-object", "Initial version"); s3Service.putObject(vBucketName, versionedObject); versionedObject = new S3Object("versioned-object", "Second version"); s3Service.putObject(vBucketName, versionedObject); versionedObject = new S3Object("versioned-object", "Final version"); s3Service.putObject(vBucketName, versionedObject); 如果通过普通的方法来获取一个开启了versioning功能的object,那么S3将反馈该object 的最新版本的数据信息,并且用户可以查看该数据的版本 ID。 versionedObject = s3Service.getObject(vBucketName, "versioned-object"); String finalVersionId = versionedObject.getVersionId(); System.out.println("Version ID: " + finalVersionId); 如果将一个 versioned 的 object 删除,那么上面介绍的一些普通的方法将不再可用。 s3Service.deleteObject(vBucketName, "versioned-object"); try { s3Service.getObject(vBucketName, "versioned-object"); } catch (S3ServiceException e) { if (e.getResponseCode() == 404) { System.out.println("Is deleted object versioned? " + e.getResponseHeaders().get(Constants.AMZ_DELETE_MARKER)); System.out.println("Delete marker version ID: " + e.getResponseHeaders().get(Constants.AMZ_VERSION_ID)); } } 这时候就需要使用一些 versioning-aware 的方法,通过指定相应的版本 ID 来获取该 object 之前版本的信息。 versionedObject = s3Service.getVersionedObject(finalVersionId, vBucketName, "versioned-object"); String versionedData = ServiceUtils.readInputStreamToString( versionedObject.getDataInputStream(), "UTF-8"); System.out.println("Data from prior version of deleted document: " + versionedData); 列出一个 bucket 中所有的对象版本信息,每个结果都是一个 S3Version 或者 S3DeleteMarker 对象。 BaseVersionOrDeleteMarker[] versions = s3Service.listVersionedObjects(vBucketName, null, null); for (int i = 0; i < versions.length; i++) { System.out.println(versions[i]); } 指定了前缀: String versionPrefix = "versioned-object"; versions = s3Service.listVersionedObjects(vBucketName, versionPrefix, null); JetS3t 提供了一个便利的方法来罗列某一个 object 的版本信息。 versions = s3Service.getObjectVersions(vBucketName, "versioned-object"); 所有的 S3 操作都有相应的 versioning-aware 方法。 versionedObject = s3Service.getVersionedObjectDetails( finalVersionId, vBucketName, "versioned-object"); // Confirm that S3 returned the versioned object you requested if (!finalVersionId.equals(versionedObject.getVersionId())) { throw new Exception("Incorrect version!"); } s3Service.copyVersionedObject(finalVersionId, vBucketName, "versioned-object", "destination-bucket", new S3Object("copied-from-version"), false, null, null, null, null); AccessControlList versionedObjectAcl = s3Service.getVersionedObjectAcl(finalVersionId, vBucketName, "versioned-object"); s3Service.putVersionedObjectAcl(finalVersionId, vBucketName, "versioned-object", versionedObjectAcl); 删除操作: s3Service.deleteVersionedObject(finalVersionId, vBucketName, "versioned-object"); // You can easily delete all the versions of an object using one of JetS3t's multi-threaded services. versions = s3Service.getObjectVersions(vBucketName, "versioned-object"); // Convert version and delete marker objects into versionId strings. String[] versionIds = BaseVersionOrDeleteMarker.toVersionIds(versions); (new S3ServiceSimpleMulti(s3Service)).deleteVersionsOfObject( versionIds, vBucketName, "versioned-object"); 2.1.10 Multi-Factor Authenticated Delete S3 提供了一些额外的数据保护策略,通过 multi-factor 认证(MFA)实现。下面的例子 就是通过 MFA 认证来删除 object 版本信息。 // Require multi-factor authentication to delete versions. s3Service.enableBucketVersioningWithMFA(vBucketName); // Check MFA status for the bucket versioningStatus = s3Service.getBucketVersioningStatus(vBucketName); System.out.println("Multi-factor auth required to delete versions ? " + versioningStatus.isMultiFactorAuthDeleteRequired()); 如果开启了 MFA,那么用户必须提供相应的序列号以及认证码才能够删除 object 的版 本信息。 String multiFactorSerialNumber = "#111222333"; String multiFactorAuthCode = "12345678"; s3Service.deleteVersionedObjectWithMFA(finalVersionId, multiFactorSerialNumber, multiFactorAuthCode, vBucketName, "versioned-object"); 如果开启了 MFA,那么必须提供 multi-factor 相关认证信息来关闭 MFA。 s3Service.disableMFAForVersionedBucket(vBucketName, multiFactorSerialNumber, multiFactorAuthCode); 如果开启了 MFA,那么必须提供 multi-factor 认证信息才能够暂停 S3 的 versioning 功能。 s3Service.suspendBucketVersioningWithMFA(vBucketName, multiFactorSerialNumber, multiFactorAuthCode); 2.2 多线程操作 JetS3t 工具箱提供了一些工具(S3ServiceMulti 和 S3ServiceSimpleMulti),使得用户可 以同时操作多个对象。在带宽条件允许下,这些工具可以使得用户更快的完成相应的操作。 这些操作可以兼容 S3Service 提供的任何线程安全的操作,例如 JetS3t 提供的一些 HTTP/REST 和 SOAP 方法。 S3ServiceMutli 专为一些有着更高需求的开发人员提供。开发人员可以在图形界面中使 用 S3ServiceMulti,并且它采用的是事件通知(event-notification)的交互方式,而非传统的 方法调用。这也意味着用户在使用 S3 上传一个大文件时,可以实时监控上传的进度(Cockpit 中就使用了该功能)。但是,这些功能会使得整个 API 变得更复杂。S3ServiceSimpleMulti 提供了一个简化的接口,开发人员可以直接使用多线程,而无需额外的操作。下面的例子将 描述如何使用 S3ServiceSimpleMulti。 2.2.1 Multiple Uploads 首先是创建一个 S3ServiceSimpleMulti 对象。 // Create a simple multi-threading service based on our existing S3Service S3ServiceSimpleMulti simpleMulti = new S3ServiceSimpleMulti(s3Service); 为了演示多线程的上传功能,这里创建了一个 bucket 并将一些对象上传到其中。 // First, create a bucket. S3Bucket bucket = new S3Bucket(awsAccessKey + ".TestMulti"); bucket = s3Service.createBucket(bucket); // Create an array of data objects to upload. S3Object[] objects = new S3Object[5]; objects[0] = new S3Object(bucket, "object1.txt", "Hello from object 1"); objects[1] = new S3Object(bucket, "object2.txt", "Hello from object 2"); objects[2] = new S3Object(bucket, "object3.txt", "Hello from object 3"); objects[3] = new S3Object(bucket, "object4.txt", "Hello from object 4"); objects[4] = new S3Object(bucket, "object5.txt", "Hello from object 5"); // Upload multiple objects. S3Object[] createdObjects = simpleMulti.putObjects(bucket, objects); System.out.println("Uploaded " + createdObjects.length + " objects"); // Perform a Details/HEAD query for multiple objects. S3Object[] objectsWithHeadDetails = simpleMulti.getObjectsHeads(bucket, objects); // Print out details about all the objects. System.out.println("Objects with HEAD Details..."); for (int i = 0; i < objectsWithHeadDetails.length; i++) { System.out.println(objectsWithHeadDetails[i]); } 2.2.2 Multiple Downloads JetS3t 也提供了多线程的下载服务,但是在使用该功能之前,用户需要准备好这些 object 存放的位置。 // Create a DownloadPackage for each object, to associate the object with an output file. DownloadPackage[] downloadPackages = new DownloadPackage[5]; downloadPackages[0] = new DownloadPackage(objects[0], new File(objects[0].getKey())); downloadPackages[1] = new DownloadPackage(objects[1], new File(objects[1].getKey())); downloadPackages[2] = new DownloadPackage(objects[2], new File(objects[2].getKey())); downloadPackages[3] = new DownloadPackage(objects[3], new File(objects[3].getKey())); downloadPackages[4] = new DownloadPackage(objects[4], new File(objects[4].getKey())); // Download the objects. simpleMulti.downloadObjects(bucket, downloadPackages); System.out.println("Downloaded objects to current working directory"); 2.2.3 Multiple Deletes 多线程的删除。 // Delete multiple objects, then the bucket too. simpleMulti.deleteObjects(bucket, objects); s3Service.deleteBucket(bucket); System.out.println("Deleted bucket: " + bucket); 2.3 高级操作 2.3.1 Managing Metadata S3Object 可以包含一些 name/value 对的 metadata 信息。这些 metadata 信息都存储在 S3 之中,并且可以通过 getObject 或 getObjectDetails 来查看这些信息。如果用户希望为 object 添加一些 metadata,那么在上传 object 之前就应该这些好这些信息。需要注意的是这些 metadata 的 name 不能有空格。 S3Object objectWithMetadata = new S3Object("metadataObject"); objectWithMetadata.addMetadata("favourite-colour", "blue"); objectWithMetadata.addMetadata("document-version", "0.3"); 2.3.2 Securing Your AWS Credentials 用户应该保管好自己的 AWS 账户信息,这些信息都是用来登录以及管理 S3 账户。JetS3t 将这些信息保存在 AWSCredentials 对象中,AWSCredentials 提供了一些方法将这些账户信 息加密之后保存在文件中。 // Save credentials to an encrypted file protected with a password. File credFile = new File("awscredentials.enc"); awsCredentials.save("password", credFile); // Load encrypted credentials from a file. AWSCredentials loadedCredentials = AWSCredentials.load("password", credFile); System.out.println("AWS Key loaded from file: " + loadedCredentials.getAccessKey()); // You won't get far if you use the wrong password... try { loadedCredentials = AWSCredentials.load("wrongPassword", credFile); } catch (S3ServiceException e) { System.err.println("Cannot load credentials from file with the wrong password!"); } 2.3.3 Access Control S3 使用 Access Control Lists 来管理 buckets 和 objects 的访问信息。在默认配置中,用户 创建的任何 bucket 或 object 都属于该用户本人,也只有该用户才有权限访问。但是,用户 可以通过一些设置使得一些 buckets 或 objects 能够被其他人访问。有关于这些权限可以参考 Amazon 的 ACL 协议。下列的代码展示了使用 ACL 协议来管理 bucket 或 object 访问权限的 方法。 // Create a bucket in S3. S3Bucket publicBucket = new S3Bucket(awsAccessKey + ".publicBucket"); s3Service.createBucket(publicBucket); // Retrieve the bucket's ACL and modify it to grant public access, // ie READ access to the ALL_USERS group. AccessControlList bucketAcl = s3Service.getBucketAcl(publicBucket); bucketAcl.grantPermission(GroupGrantee.ALL_USERS, Permission.PERMISSION_READ); // Update the bucket's ACL. Now anyone can view the list of objects in this bucket. publicBucket.setAcl(bucketAcl); s3Service.putBucketAcl(publicBucket); System.out.println("View bucket's object listing here: http://s3.amazonaws.com/" + publicBucket.getName()); 2.3.4 Temporary Public URLs 用户可以通过某个 URL 地址来访问 S3 中的某个 object,这个 URL 地址是有时效的。 // Create a private object in S3. S3Bucket privateBucket = new S3Bucket("privateBucket"); S3Object privateObject = new S3Object( privateBucket, "privateObject.txt", "This object is private"); s3Service.createBucket(privateBucket); s3Service.putObject(privateBucket, privateObject); // Determine what the time will be in 5 minutes. Calendar cal = Calendar.getInstance(); cal.add(Calendar.MINUTE, 5); Date expiryDate = cal.getTime(); String signedUrl = S3Service.createSignedGetUrl(privateBucket.getName(), privateObject.getKey(), awsCredentials, expiryDate); System.out.println("Signed URL: " + signedUrl); 2.3.5 S3 POST Forms 当创建一个 S3 的 POST form 时,那么通过浏览器访问该网页的其它用户都可以上传文 件到 S3 账户中,不需要安装任何 S3 的客户端软件。更多信息请参照 S3 POST4相关文档。 在这里我们将创建一个不涉及任何 policy 的 POST form,这也意味着这个 form 不会失 效,也不会有其它的限制条件。当且仅当目标 bucket 开放了写权限,这个窗口才可以工作。 String unrestrictedForm = S3Service.buildPostForm("public-bucket", "${filename}"); 为了使用这个 form,那么将它保存成 UTF-8 编码的 html 文件,然后通过浏览器打开即 可。接下来我们将创建一系列带有约束条件的 POST form,允许用户上传图像文件到一个受 保护的 bucket 之中。上传成功后,将用户转到另外一个页面上。 String bucketName = "test-bucket"; String key = "uploads/images/pic.jpg"; String[] inputFields = new String[] { "", "", "" }; 需要说明的是所有的 POST 请求都会被强制的加上 bucket 和 key 的值。除了这两个强 制的值之外,我们还可以加上一个 field 用来控制上传文件的大小。 String[] conditions = { S3Service.generatePostPolicyCondition_Equality("bucket", bucketName), S3Service.generatePostPolicyCondition_Equality("key", key), S3Service.generatePostPolicyCondition_Range(10240, 204800), // Conditions to allow the additional fields specified above S3Service.generatePostPolicyCondition_Equality("acl", "public-read"), S3Service.generatePostPolicyCondition_Equality("Content-Type", "image/jpeg"), S3Service.generatePostPolicyCondition_Equality("success_action_redirect", "http://localhost/post_upload") }; // Form will expire in 24 hours cal = Calendar.getInstance(); cal.add(Calendar.HOUR, 24); Date expiration = cal.getTime(); 4 http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingHTTPPOST.html // Generate the form. String restrictedForm = S3Service.buildPostForm( bucketName, key, awsCredentials, expiration, conditions, inputFields, null, true); 2.3.6 Activate Requester Pays for a bucket 在 S3 的默认配置中,一个 bucket 的所有上传下载等操作产生的费用都由这个 bucket 所属的用户来支付。S3 的 Requester Pays 特性允许用户将自己的 bucket 配置成请求者支付 模式,即请求和传输的费用由每个 requester 来承担。需要说明的是,只有 S3 的 REST API 支持 Requester Pays,因此在编写代码时必须使用 RestS3Service,而不是 SoapS3Service。 // Set a bucket to be Requester Pays s3Service.setRequesterPaysBucket(bucketName, true); // Set a bucket to be Owner pays (the default value for S3 buckets) s3Service.setRequesterPaysBucket(bucketName, false); // Find out whether a bucket is configured as Requester pays s3Service.isRequesterPaysBucket(bucketName); 2.3.7 Access a Requester Pays bucket 当一个 bucket 设置成 Requester Pays 模式时,AWS 的其它用户在满足以下两个条件后 就可以上传/下载该 bucket 中的文件:有 ACL 的相应权限;愿意承担相关操作的费用。通过 设置标签位 RequesterPaysEnabled 来使用 Requester Pays 相关的操作。JetS3t 的默认配置设置 RequesterPaysEnabled 为 false:httpclient.requester-pays-buckets-enabled=false。 s3Service.setRequesterPaysEnabled(true); 用户在操作一个 Requester Pays 的 bucket 时可以生成一个 URL 地址,允许第三方用户 访问该 bucket 中的一些对象。 // Generate a signed GET URL for Map httpHeaders = null; long expirySecsAfterEpoch = System.currentTimeMillis() / 1000 + 300; boolean isVirtualHost = false; boolean isHttpsUrl = false; String requesterPaysSignedGetUrl = S3Service.createSignedUrl("GET", bucketName, "object-name", Constants.REQUESTER_PAYS_BUCKET_FLAG, // Include Requester Pays flag httpHeaders, awsCredentials, expirySecsAfterEpoch, isVirtualHost, isHttpsUrl); 2.3.8 Amazon DevPay S3 Accounts Amazon 的 DevPay 服务允许一些代理出售 user-pays 的 S3 账户。为了访问 DevPay 产品 中的 S3 账户,JetS3t 需要添加一些额外的账户信息,包括 DevPay User Token 和 DevPay Product Token。 AWSDevPayCredentials devPayCredentials = new AWSDevPayCredentials( "YOUR_AWS_ACCESSS_KEY", "YOUR_AWS_SECRET_KEY", "DEVPAY_USER_TOKEN", "DEVPAY_PRODUCT_TOKEN"); 一旦设置好这些信息,那么用户就可以直接操作 DevPay 账户。 S3Service devPayService = new RestS3Service(devPayCredentials); devPayService.listAllBuckets(); 同样也可以为 DevPay S3 账户创建一些 URL 地址。 cal = Calendar.getInstance(); cal.add(Calendar.MINUTE, 5); String signedDevPayUrl = S3Service.createSignedGetUrl( "devpay-bucket-name", "devpay-object-name", devPayCredentials, cal.getTime());
还剩15页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 20 金币 [ 分享pdf获得金币 ] 2 人已下载

下载pdf

pdf贡献者

jiagu

贡献于2011-07-26

下载需要 20 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf