对象存储 OSS/SDK 手册 SDK 手册 Java-SDK 前言 SDK 下载 Java SDK 开发包最新版本 2.2.1:java_sdk_ zip; github 地址 : 版本迭代详

Size: px
Start display at page:

Download "对象存储 OSS/SDK 手册 SDK 手册 Java-SDK 前言 SDK 下载 Java SDK 开发包最新版本 2.2.1:java_sdk_ zip; github 地址 : 版本迭代详"

Transcription

1 对象存储 OSS SDK 手册

2 对象存储 OSS/SDK 手册 SDK 手册 Java-SDK 前言 SDK 下载 Java SDK 开发包最新版本 2.2.1:java_sdk_ zip; github 地址 : 版本迭代详情参考这里 简介 OSS Java SDK 适用于 SDK 6 及以上版本 ; 本文档主要介绍 OSS Java SDK 的安装 使用及注意事项 ; 并且假设您已经开通了阿里云 OSS 服务, 并创建了 AccessKeyId 和 AccessKeySecret 如果您还没有开通或者还不了解阿里云 OSS 服务, 请登录 OSS 产品主页了解 如果还没有创建 AccessKeyId 和 AccessKeySecret, 请到阿里云 Access Key 管理创建 Access Key 兼容性 对于 2.. 系列 SDK: 接口 : 命名空间 : 兼容 兼容 对于 1.0. 系列 SDK: 接口 : 兼容 1

3 对象存储 OSS/ 周边工具 命名空间 : 不兼容 :2.0.0 版本移除 1.0.x 版本中 OTS 相关代码, 调整包结构, 将包名称 com.aliyun.openservices. 与 com.aliyun.openservices.oss. 更换为 com.aliyun.oss.* 安装 环境准备 适用于 JDK 6 及以上版本 安装方式 方式一 : 在 Maven 项目中加入依赖项 ( 推荐方式 ) 在 Maven 工程中使用 OSS Java SDK 只需在 pom.xml 中加入相应依赖即可 以 版本为例, 在 dependencies 标签内加入如下内容 : <dependency> <groupid>com.aliyun.oss</groupid> <artifactid>aliyun-sdk-oss</artifactid> <version>2.2.1</version> </dependency> 方式二 : 在 Eclipse 项目中导入 JAR 包 以 版本为例, 步骤如下 : 下载 Java SDK 开发包版本号 2.2.1:java_sdk_ zip; 解压该开发包 ; 将解压后文件夹中的文件 : aliyun-sdk-oss-<versionid>.jar 以及 lib 文件夹下的所有文件拷贝到您的项目中 ; 在 Eclipse 中选择您的工程, 右击 -> Properties -> Java Build Path -> Add JARs; 选中您在第三步拷贝的所有 JAR 文件 ; 经过以上几步, 您就可以在 Eclipse 项目中使用 OSS Java SDK 示例工程 OSS Java SDK 提供了基于 maven ant 的示例工程, 您可以在本地设备上编译运行示例工程 您也可以以示例工程为基础开发您的应用 2

4 性能测试 /Lite 用户使用手册 mvn 示例工程 ant 示例工程 提示 : 编译运行前, 请修改 HelloOSS.java 中 endpoint/accesskeyid/accesskeysecret/bucketname 为您的真实信息 ; 工程的编译运行方法, 参看工程目录下 README.md 示例程序 OSS Java SDK 提供丰富的示例程序, 方便用户参考或直接使用 您可以通过以下两种方式获取示例程序 : github 查看下载,OSS Java SDK github 下的 src/samples 为示例程序 ; 下载 OSS Java SDK 开发包, 如 2.2.1, 解压后 aliyun_java_sdk_ /samples 为示例程序 ; 初始化 OSSClient 是 OSS 服务的 Java 客户端, 它为调用者提供一系列与 OSS 进行交互的接口, 可用于管理 操作存储空间 (Bucket) 和文件 (Object) 等 使用 SDK 发起 OSS 请求, 您需要初始化一个 OSSClient 实例, 并根据您的需要修改 ClientConfiguration 实例的默认配置项 确定 Endpoint 请先阅读开发人员指南中关于访问域名和数据中心和自定义访问域名的部分, 理解 Endpoint 相关的概念 Endpoint 可以有以下几种形式 : 示例 说明 以 HTTP 协议, 公网访问杭州区域的 Bucket 以 HTTPS 协议, 公网范围北京区域的 Bucket 以 HTTP 协议, 通过用户自定义域名 (CNAME) 访问某个 Bu 配置密钥 要接入阿里云 OSS, 您需要拥有一个有效的 Access Key( 包括 AccessKeyId 和 3

5 性能测试 /Lite 用户使用手册 AccessKeySecret) 用来进行签名认证 可以通过如下步骤获得 : 注册阿里云帐号 申请 AccessKey 获取 AccessKeyId 和 AccessKeySecret 之后, 您便可以按照以下步骤进行初始化 : 新建 Client 使用 OSS 域名新建 OSSClient 新建一个 OSSClient 代码如下 : String endpoint = "** Provide OSS endpoint ***"; String accesskeyid = "*** Provide your AccessKeyId ***"; String accesskeysecret = "*** Provide your AccessKeySecret ***"; // Create a new OSSClient instance OSSClient client = new OSSClient(endpoint, accesskeyid, accesskeysecret); // Do some operations with the instance... // Shutdown the instance to release any allocated resources client.shutdown(); 使用自定义域名 (CNAME) 新建 OSSClient 下面的代码让客户端使用 CNAME 访问 OSS 服务, 只需将 endpoint 设置为 CNAME 即可 : String endpoint = "*** Provide your CNAME ***"; String accesskeyid = "*** Provide your AccessKeyId ***"; String accesskeysecret = "*** Provide your AccessKeySecret ***"; // Create a new client configuration instance ClientConfiguration conf = new ClientConfiguration(); conf.setsupportcname(true); // Create a new OSSClient instance with CNAME support OSSClient client = new OSSClient(endpoint, accesskeyid, accesskeysecret, conf); // Do some operations with the instance... // Shutdown the instance to release any allocated resources client.shutdown(); 注意 : 使用 CNAME 时, 无法使用 ListBuckets 接口 4

6 性能测试 /Lite 用户使用手册 配置 OSSClient 如果您想修改 OSSClient 的一些默认配置项, 可以在构造 OSSClient 的时候传入 ClientConfiguration 实例 ClientConfiguration 是 OSSClient 实例的配置类, 可配置代理 连接超时 最大连接数等选项 设置网络参数 我们可以用 ClientConfiguration 设置一些网络参数 : // Create a new client configuration instance ClientConfiguration conf = new ClientConfiguration(); // Set the maximum number of allowed open HTTP connections conf.setmaxconnections(100); // Set the amount of time to wait (in milliseconds) when initially establishing // a connection before giving up and timing out conf.setconnectiontimeout(5000); // Set the maximum number of retry attempts for failed retryable requests conf.setmaxerrorretry(3); // Set the amount of time to wait (in milliseconds) for data to betransfered over // an established connection before the connection times out and is closed conf.setsockettimeout(2000); // Create a new OSSClient instance OSSClient client = new OSSClient(endpoint, accesskeyid, accesskeysecret, conf); 通过 ClientConfiguration 可以设置的参数有 : 参数 描述 UserAgent 用户代理, 指 HTTP 的 User-Agent 头 默认为 "aliyun-sdk-java" ProxyHost 代理服务器主机地址 ProxyPort 代理服务器端口 ProxyUsername 代理服务器验证的用户名 ProxyPassword 代理服务器验证的密码 ProxyDomain 访问 NTLM 验证的代理服务器的 Windows 域名 ProxyWorkstation NTLM 代理服务器的 Windows 工作站名称 MaxConnections 允许打开的最大 HTTP 连接数 默认为 1024 SocketTimeout Socket 层传输数据的超时时间 ( 单位 : 毫秒 ) 默认为 毫秒 ConnectionTimeout 建立连接的超时时间 ( 单位 : 毫秒 ) 默认为 毫秒 ConnectionRequestTimeout 从连接池中获取连接的超时时间 ( 单位 : 毫秒 ) 默认不超时 IdleConnectionTime 关闭空闲该时长的连接 ( 单位 : 毫秒 ) 默认为 60 秒 MaxErrorRetry 可重试的请求失败后最大的重试次数 默认为 3 次 Protocol 连接 OSS 所采用的协议 (HTTP/HTTPS), 默认为 HTTP SupportCname 是否支持 CNAME 作为 Endpoint, 默认支持 CNAME 5

7 性能测试 /Lite 用户使用手册 SLDEnabled 是否开启二级域名 (Second Level Domain) 的访问方式, 默认不开启 快速入门 确认您已经理解 OSS 基本概念, 如 Bucket Object Endpoint AccessKeyId 和 AccessKeySecret 等 本节您将学到如何快速使用 OSS Java SDK 进行若干常见操作, 如创建存储空间 上传文件 下载文件等 1. 初始化 OSSClient 实例 在您向 OSS 发送任一 HTTP 请求之前, 必须先创建一个 OSSClient 实例 : String endpoint = "** Provide OSS endpoint ***"; String accesskeyid = "*** Provide your AccessKeyId ***"; String accesskeysecret = "*** Provide your AccessKeySecret ***"; // Create a new OSSClient instance OSSClient client = new OSSClient(endpoint, accesskeyid, accesskeysecret); // Do some operations with the instance... // Shutdown the instance to release any allocated resources client.shutdown(); 提示 : 当不再向 OSS 发送 HTTP 请求时, 请显示调用 OSSClient#shutdown 释放任何已经分配的资源 上述代码中,accessKeyId 与 accesskeysecret 变量值由系统分配给用户, 称为 ID 对, 用于标识用户, 可能属于您的阿里云账号或者 RAM 账号为访问 OSS 做签名验证 2. 新建 Bucket Bucket 是 OSS 全局命名空间, 相当于数据的容器, 可以存储若干 Object 以下代码展示如何新建一个 Bucket: String bucketname = "my-first-oss-bucket" + UUID.randomUUID(); client.createbucket(bucketname); 6

8 性能测试 /Lite 用户使用手册 关于 Bucket 的命名规范, 参见 Bucket 中的命名规范 3. 上传 Object 以下代码展示如何上传某一 Object 至 OSS: String key = "MyObjectKey"; String content = "Thank you for using OSS SDK for Java"; client.putobject(bucketname, key, new ByteArrayInputStream(content.getBytes())); 提示 : SDK 通过 InputStream 的形式上传至 OSS 关于上传 Object 更详细的信息, 参见 Object 中的上传 Object 4. 下载 Object 以下代码展示如何简单的获取某一 Object 的文本内容 : OSSObject object = client.getobject(new GetObjectRequest(bucketName, key)); InputStream content = object.getobjectcontent(); if (content!= null) BufferedReader reader = new BufferedReader(new InputStreamReader(content)); while (true) String line = reader.readline(); if (line == null) break; System.out.println(" content.close(); " + line); 提示 : 调用 OSSClient#GetObject 返回一个 OSSObject 实例, 该实例包含文件内容及其元信息 调用 OSSObject#GetObjectContent 获取文件输入流, 可读取此输入流获取其内容, 用完之后关闭这个流 5. 列举 Object 当完成一系列上传 Object 操作后, 可能需要查看某个 Bucket 下包含哪些 Object 以下代码展示如何列举指定 Bucket 下的 Object: 7

9 性能测试 /Lite 用户使用手册 ObjectListing objectlisting = client.listobjects(new ListObjectsRequest(bucketName).withPrefix("My")); for (OSSObjectSummary objectsummary : objectlisting.getobjectsummaries()) System.out.println(" - " + objectsummary.getkey() + " " + "(size = " + objectsummary.getsize() + ")"); 调用 OSSClient#listObjects 返回 ObjectListing 实例, 该实例包含此次 listobject 请求的返回结果, 可通过 ObjetListing#getObjectSummaries 获取所有 Object 的描述信息 示例程序 以下是一个完整的示例程序, 展示如何创建存储空间 上传文件 下载文件 查看文件列表 删除文件 删除存储空间等操作 import java.io.bufferedreader; import java.io.file; import java.io.fileoutputstream; import java.io.ioexception; import java.io.inputstream; import java.io.inputstreamreader; import java.io.outputstreamwriter; import java.io.writer; import java.util.uuid; import com.aliyun.oss.clientexception; import com.aliyun.oss.ossclient; import com.aliyun.oss.ossexception; import com.aliyun.oss.model.bucket; import com.aliyun.oss.model.getobjectrequest; import com.aliyun.oss.model.listobjectsrequest; import com.aliyun.oss.model.ossobject; import com.aliyun.oss.model.ossobjectsummary; import com.aliyun.oss.model.objectlisting; import com.aliyun.oss.model.putobjectrequest; /** * This sample demonstrates how to get started with basic requests to Aliyun OSS * using the OSS SDK for Java. */ public class GetStartedSample private static String endpoint = "*** Provide OSS endpoint ***"; private static String accesskeyid = "*** Provide your AccessKeyId ***"; private static String accesskeysecret = "*** Provide your AccessKeySecret ***"; private static OSSClient client = null; public static void main(string[] args) throws IOException /* * Constructs a client instance with your account for accessing OSS */ 8

10 开放数据处理服务 ODPS/ 安全指南 client = new OSSClient(endpoint, accesskeyid, accesskeysecret); String bucketname = "my-first-oss-bucket" + UUID.randomUUID(); String key = "MyObjectKey"; System.out.println("==========================================="); System.out.println("Getting Started with OSS SDK for Java"); System.out.println("===========================================\n"); try /* * Create a new OSS bucket */ System.out.println("Creating bucket " + bucketname + "\n"); client.createbucket(bucketname); /* * Determine whether the newly bucket exists */ boolean exists = client.doesbucketexist(bucketname); System.out.println("Does bucket " + bucketname + " exist? " + exists + "\n"); /* * List the buckets in your account */ System.out.println("Listing buckets"); for (Bucket bucket : client.listbuckets()) System.out.println(" - " + bucket.getname()); System.out.println(); /* * Upload an object to your bucket */ System.out.println("Uploading a new object to OSS from a file\n"); client.putobject(new PutObjectRequest(bucketName, key, createsamplefile())); /* * Determine whether an object residents in your bucket */ exists = client.doesobjectexist(bucketname, key); System.out.println("Does object " + bucketname + " exist? " + exists + "\n"); /* * Download an object from your bucket */ System.out.println("Downloading an object"); OSSObject object = client.getobject(new GetObjectRequest(bucketName, key)); System.out.println("Content-Type: " + object.getobjectmetadata().getcontenttype()); displaytextinputstream(object.getobjectcontent()); /* * List objects in your bucket by prefix */ System.out.println("Listing objects"); ObjectListing objectlisting = client.listobjects(new ListObjectsRequest(bucketName) 9

11 对象存储 OSS/ 图片服务手册.withPrefix("My")); for (OSSObjectSummary objectsummary : objectlisting.getobjectsummaries()) System.out.println(" - " + objectsummary.getkey() + " " + "(size = " + objectsummary.getsize() + ")"); System.out.println(); /* * Delete an object */ System.out.println("Deleting an object\n"); client.deleteobject(bucketname, key); /* * Delete a bucket */ System.out.println("Deleting bucket " + bucketname + "\n"); client.deletebucket(bucketname); catch (OSSException oe) System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message: " + oe.geterrorcode()); System.out.println("Error Code: " + oe.geterrorcode()); System.out.println("Request ID: " + oe.getrequestid()); System.out.println("Host ID: " + oe.gethostid()); catch (ClientException ce) System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message: " + ce.getmessage()); finally /* * Do not forget to shut down the client finally to release all allocated resources. */ client.shutdown(); private static File createsamplefile() throws IOException File file = File.createTempFile("oss-java-sdk-", ".txt"); file.deleteonexit(); Writer writer = new OutputStreamWriter(new FileOutputStream(file)); writer.write("abcdefghijklmnopqrstuvwxyz\n"); writer.write(" \n"); writer.close(); return file; private static void displaytextinputstream(inputstream input) throws IOException BufferedReader reader = new BufferedReader(new InputStreamReader(input)); while (true) String line = reader.readline(); if (line == null) break; 10

12 阿里云大数据平台 / 推荐引擎 System.out.println(" System.out.println(); " + line); reader.close(); 管理 Bucket 新建 Bucket 如下代码展示如何新建一个 Bucket: // Create a new OSSClient instance OSSClient client = new OSSClient(...); String bucketname = "my-oss-bucket"; client.createbucket(bucketname); 提示 : 由于 Bucket 的名字是全局唯一的, 所以必须保证您的 Bucket 名称不与别人重复 列举 Bucket 使用 OSSClient#listBuckets 列举指定用户的 Bucket 列表, 并可以指定 prefix marker maxkeys 等参数限定返回的结果列表 以下代码展示如何采用简单的方式列举指定用户的 Bucket 列表 : for (Bucket bkt : client.listbuckets()) System.out.println(" - " + bkt.getname()); 使用 CNAME 进行访问 当用户将自己的域名 CNAME 指向自己的一个 bucket 的域名后, 用户可以使用自己的域名来访问 OSS: String endpoint = "*** Provide your CNAME ***"; 11

13 阿里云大数据平台 / 推荐引擎 String accesskeyid = "*** Provide your AccessKeyId ***"; String accesskeysecret = "*** Provide your AccessKeySecret ***"; // Create a new OSSClient instance with CNAME support OSSClient client = new OSSClient(endpoint, accesskeyid, accesskeysecret); 提示 : 用户只需要在创建 OSSClinet 类实例时, 将原本填入该存储空间的 endpoint 更换成 CNAME 后的域名, 默认开启 CNAME 支持 同时需要注意的是, 使用该 OSSClient 实例的后续操作中, 存储空间的名称只能填成被指向的存储空间名称 判断 Bucket 是否存在 在创建 Bucket 之前, 您可以使用 OSSClient#doesBucketExist 接口判断该 Bucket 是否已存在 以下代码展示如何判断指定 Bucket 是否存在 : boolean exists = client.doesbucketexist(bucketname); 设置 Bucket ACL Bucket 的 ACL 包含三类 :Private( 私有 ), PublicRead( 公共读 ), PublicReadWrite( 公共读写 ) 以下代码展示如何指定 Bucket 的 ACL 设置为私有 : client.setbucketacl(bucketname, CannedAccessControlList.Private); 获取 Bucket ACL 以下代码展示如何获取 Bucket 的 ACL: AccessControlList acl = client.getbucketacl(bucketname); System.out.println(acl.toString()); 获取 Bucket Location 以下代码展示如何获取 Bucket 的 Location: String location = client.getbucketlocation(bucketname); 12

14 性能测试 /Lite 实践指南 获取 Bucket Info Bucket 的 Info 包括 Location CreationDate Owner 及权限等信息 以下代码展示如何获取 Bucket 的 Info: BucketInfo info = secondclient.getbucketinfo(bucketname); info.getbucket().getlocation(); info.getbucket().getcreationdate(); info.getbucket().getowner(); info.getgrants(); 删除 Bucket 以下代码展示如何删除某一 Bucket: client.deletebucket(bucketname); 提示 : 如果存储空间不为空 ( 存储空间中有文件或者分片上传碎片 ), 则存储空间无法删除 必须先删除存储空间中的所有文件后, 存储空间才能成功删除 上传文件 在 OSS 中, 用户操作的基本数据单元是文件 (Object) 单个文件最大允许大小根据上传数据方式不同而不同,Put Object 方式最大不能超过 5GB, 使用 multipart 上传方式文件大小不能超过 48.8TB 简单上传 SDK 提供两种上传方式 : 一种是直接使用 InputStream 作为 Object 数据源, 另一种则使用本地文件作为 Object 数据源 上传 InputStream String key = "MyObjectKey"; String content = "Thank you for using OSS SDK for Java"; client.putobject(bucketname, key, new ByteArrayInputStream(content.getBytes())); 13

15 性能测试 /Lite 实践指南 提示 : 输入流无需主动关闭, 无论正常或异常,SDK 确保请求结束时关闭输入流 上传本地文件 String key = "MyObjectKey"; String localfilepath = "*** Provide local file path ***"; client.putobject(bucketname, key, new File(localFilePath)); 设定 Object 的 Http Header OSS 服务允许用户自定义 Object 的 Http Header 下面代码为 Object 设置了过期时间 : // 初始化上传输入流 InputStream content =...; // 创建上传 Object 的 Metadata ObjectMetadata meta = new ObjectMetadata(); // 设置 ContentLength 为 1000 meta.setcontentlength(1000); client.putobject(bucketname, key, content, meta); Java SDK 支持的 Http Header 有四种, 分别为 :Cache-Control Content-Disposition Content-Encoding Expires 它们的相关介绍见 RFC2616 用户自定义元信息 OSS 支持用户自定义元信息来对 Object 进行描述 比如 : // 设置自定义元信息 name 的值为 my-data meta.addusermetadata("name", "my-data"); // 上传 object client.putobject(bucketname, key, content, meta); 提示 : 在上面代码中, 用户自定义了一个名称为 "name", 值为 "my-data" 的元信息 当用户下载此文件的时候, 此元信息也可以一并得到 一个文件可以有多个元信息, 但元信息的总大小不能超过 8KB 14

16 性能测试 /Lite 实践指南 重要 : 元信息的名称大小写不敏感, 比如用户上传文件时, 定义名字为 "Name" 的元信息, 获取时指定元信息的名称为 "name" 即可 注意 : 使用上述方法上传最大文件不能超过 5G 如果超过可以使用 MutipartUpload 上传 使用 Chunked 编码上传 当无法确认上传内容的长度时 ( 比如 SocketStream 作为上传的数据源, 边读取边上传, 直至 Socket 关闭为止 ), 需要采用 chunked 编码 putobject chunked 编码当显式设置 ObjectMetadata 实例中的 ContentLength 属性时, 采用普通方式上传 ( 由 Content-Length 请求头决定请求 body 的长度 ); 反之则采用 chunked 编码方式上传 FileInputStream fin = new FileInputStream(new File(filePath)); // 如果不设置 content-length, 默认为 chunked 编码 PutObjectResult result = client.putobject(bucketname, key, fin); 创建模拟文件夹 OSS 服务是没有文件夹这个概念的, 所有元素都是以文件来存储 但给用户提供了创建模拟文件夹的方式, 如下代码 : /* * Create an empty folder without request body, note that the key must be * suffixed with a slash */ final String keysuffixwithslash = "MyObjectKey/"; client.putobject(bucketname, keysuffixwithslash, new ByteArrayInputStream(new byte[0])); 提示 : 创建模拟文件夹本质上来说是创建了一个名字以 "/" 结尾的文件 对于这个文件照样可以上传下载, 只是控制台会对以 "/" 结尾的文件以文件夹的方式展示 更多内容请参考 (doc/[5]sdk/java-sdk/ 管理文件.md) 分片上传除了通过 PutObject 接口上传文件到 OSS 以外,OSS 还提供了另外一种上传模式 -- 15

17 性能测试 /Lite 实践指南 Multipart Upload 用户可以在如下的应用场景内 ( 但不仅限于此 ), 使用 Multipart Upload 上传模式, 如 : 需要支持断点上传 上传超过 100MB 大小的文件 网络条件较差, 和 OSS 的服务器之间的链接经常断开 上传文件之前, 无法确定上传文件的大小 下面我们将一步步学习怎样实现 Multipart Upload 分步完成 Multipart Upload 初始化 Multipart Upload 调用 OSSClient#initiateMultipartUpload 初始化一个分片上传事件 : InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, key); InitiateMultipartUploadResult result = client.initiatemultipartupload(request); String uploadid = result.getuploadid(); 提示 : 我们用 InitiateMultipartUploadRequest 来指定上传文件的名字和所属存储空间 (Bucket) 在 InitiateMultipartUploadRequest 中, 您也可以设置 ObjectMeta, 但是不必指定其中的 ContentLength initiatemultipartupload 的返回结果中含有 UploadId, 它是区分分片上传事件的唯一标识, 在后面的操作中, 我们将用到它 上传分片 调用 OSSClient#uploadPart 上传某一分片 : final String filepath = "*** Provide file path ****"; InputStream instream = new FileInputStream(new File(filePath)); UploadPartRequest uploadpartrequest = new UploadPartRequest(); uploadpartrequest.setbucketname(bucketname); uploadpartrequest.setkey(key); uploadpartrequest.setuploadid(uploadid); uploadpartrequest.setinputstream(instream); uploadpartrequest.setpartsize(partsize); uploadpartrequest.setpartnumber(partnumber); UploadPartResult uploadpartresult = client.uploadpart(uploadpartrequest); 16

18 性能测试 /Lite 实践指南 注意 : UploadPart 方法要求除最后一个 Part 以外, 其他的 Part 大小都要大于 100KB 但是 Upload Part 接口并不会立即校验上传 Part 的大小 ( 因为不知道是否为最后一块 ); 只有当 Complete Multipart Upload 的时候才会校验 OSS 会将服务器端收到 Part 数据的 MD5 值放在 ETag 头内返回给用户 为了保证数据在网络传输过程中不出现错误,SDK 会自动设置 Content- MD5,OSS 会计算上传数据的 MD5 值与 SDK 计算的 MD5 值比较, 如果不一致返回 InvalidDigest 错误码 Part 号码的范围是 1~10000 如果超出这个范围,OSS 将返回 InvalidArgument 的错误码 每次上传 part 时都要把流定位到此次上传块开头所对应的位置 每次上传 part 之后,OSS 的返回结果会包含一个 PartETag 对象, 他是上传块的 ETag 与块编号 (PartNumber) 的组合, 在后续完成分片上传的步骤中会用到它, 因此我们需要将其保存起来 一般来讲我们将这些 PartETag 对象保存到 List 中 完成分片上传 调用 OSSClient#completeMultipartUpload 完成某一分片上传事件 : CompleteMultipartUploadRequest completemultipartuploadrequest = new CompleteMultipartUploadRequest(bucketName, key, uploadid, partetags); client.completemultipartupload(completemultipartuploadrequest); 注意 : 上面代码中的 partetags 就是进行分片上传中保存的 partetag 的列表,OSS 收到用户提交的 Part 列表后, 会逐一验证每个数据 Part 的有效性 当所有的数据 Part 验证通过后,OSS 会将这些 part 组合成一个完整的文件 取消分片上传事件 调用 OSSClient#abortMultipartUpload 取消分片上传事件 : AbortMultipartUploadRequest abortmultipartuploadrequest = new AbortMultipartUploadRequest(bucketName, key, uploadid); client.abortmultipartupload(abortmultipartuploadrequest); 获取存储空间内所有分片上传事件 17

19 性能测试 /Lite 实践指南 调用 OSSClient#listMultipartUploads 获取存储空间内所有分片上传事件 : ListMultipartUploadsRequest listmultipartuploadsrequest = new ListMultipartUploadsRequest(bucketName); MultipartUploadListing multipartuploadlisting = client.listmultipartuploads(listmultipartuploadsrequest); 重要 : 默认情况下, 如果存储空间中的分片上传事件的数量大于 1000, 则只会返回 1000 个文件, 且返回结果中 IsTruncated 为 false, 返回 NextKeyMarker 和 NextUploadIdMarker 作为下次读取的起点 如果没有一次性获取所有的上传事件, 可以采用分页列举的方式 获取所有已上传分片 调用 OSSClient#listParts 获取某个上传事件所有已上传分片 : ListPartsRequest listpartsrequest = new ListPartsRequest(bucketName, key, uploadid); PartListing partlisting = client.listparts(listpartsrequest); 提示 : 默认情况下, 如果存储空间中的分片上传事件的数量大于 1000, 则只会返回 1000 个 Multipart Upload 信息, 且返回结果中 IsTruncated 为 false, 并返回 NextPartNumberMarker 作为下此读取的起点 如果没有一次性获取所有的上传分片, 可以采用分页列举的方式 断点续传上传 当上传大文件时, 如果网络不稳定或者程序崩溃了, 则整个上传就失败了 用户不得不重头再来, 这样做不仅浪费资源, 在网络不稳定的情况下, 往往重试多次还是无法完成上传 通过 OSSClient.uploadFile 接口来实现断点续传上传, 参数是 UploadFileRequest, 该请求有以下参数 : bucket 存储空间名字, 必选参数, 通过构造方法设置 key 上传到 OSS 的 Object 名字, 必选参数, 通过构造方法设置 uploadfile 待上传的本地文件, 必选参数, 通过构造方法或 setuploadfile 设置 partsize 分片大小, 从 100KB 到 5GB, 单位是 Byte, 可选参数, 默认 100K, 通过 setpartsize 设置 tasknum 分片上传并发数, 可选参数, 默认为 1, 通过 settasknum 设置 enablecheckpoint 上传是否开启断点续传, 可选参数, 默认断点续传功能关闭, 通过 setenablecheckpoint 设置 18

20 性能测试 /Lite 实践指南 checkpointfile 开启断点续传时, 需要在本地记录分片上传结果, 如果上传失败, 下次不会再上传已经成功的分片, 可选参数, 默认与待上传的本地文件同目录, 为 uploadfile.ucp, 可以通过 setcheckpointfile 设置 objectmetadata,object 的元数据, 可选参数, 用户可以通过 setobjectmetadata 设置 callback 上传成功后的回调, 可选参数, 用户可以通过 setcallback 设置 其实现的原理是将要上传的文件分成若干个分片分别上传, 最后所有分片都上传成功后, 完成整个文件的上传 在上传的过程中会记录当前上传的进度信息 ( 记录在 checkpoint 文件中 ), 如果上传过程中某一分片上传失败, 再次上传时会从 checkpoint 文件中记录的点继续上传 这要求再次调用时要指定与上次相同的 checkpoint 文件 上传完成后,checkpoint 文件会被删除 UploadFileRequest uploadfilerequest = new UploadFileRequest("bucketName", "key"); uploadfilerequest.setuploadfile("localfile"); uploadfilerequest.settasknum(10); uploadfilerequest.setenablecheckpoint(true); UploadFileResult uploadres = ossclient.uploadfile(uploadfilerequest); 简单上传 下载示例 import java.io.bufferedreader; import java.io.bytearrayinputstream; import java.io.file; import java.io.fileoutputstream; import java.io.ioexception; import java.io.inputstream; import java.io.inputstreamreader; import java.io.outputstreamwriter; import java.io.writer; import com.aliyun.oss.clientexception; import com.aliyun.oss.ossclient; import com.aliyun.oss.ossexception; import com.aliyun.oss.model.getobjectrequest; import com.aliyun.oss.model.ossobject; import com.aliyun.oss.model.putobjectrequest; /** * This sample demonstrates how to upload/download an object to/from * Aliyun OSS using the OSS SDK for Java. */ public class SimpleGetObjectSample private static String endpoint = "*** Provide OSS endpoint ***"; private static String accesskeyid = "*** Provide your AccessKeyId ***"; private static String accesskeysecret = "*** Provide your AccessKeySecret ***"; private static String bucketname = "*** Provide bucket name ***"; 19

21 性能测试 /Lite 实践指南 private static String key = "*** Provide object key ***"; public static void main(string[] args) throws IOException /* * Constructs a client instance with your account for accessing OSS */ OSSClient client = new OSSClient(endpoint, accesskeyid, accesskeysecret); try /** * Note that there are two ways of uploading an object to your bucket, the one * by specifying an input stream as content source, the other by specifying a file. */ /* * Upload an object to your bucket from an input stream */ System.out.println("Uploading a new object to OSS from an input stream\n"); String content = "Thank you for using Aliyun Object Storage Service"; client.putobject(bucketname, key, new ByteArrayInputStream(content.getBytes())); /* * Upload an object to your bucket from a file */ System.out.println("Uploading a new object to OSS from a file\n"); client.putobject(new PutObjectRequest(bucketName, key, createsamplefile())); /* * Download an object from your bucket */ System.out.println("Downloading an object"); OSSObject object = client.getobject(new GetObjectRequest(bucketName, key)); System.out.println("Content-Type: " + object.getobjectmetadata().getcontenttype()); displaytextinputstream(object.getobjectcontent()); catch (OSSException oe) System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message: " + oe.geterrorcode()); System.out.println("Error Code: " + oe.geterrorcode()); System.out.println("Request ID: " + oe.getrequestid()); System.out.println("Host ID: " + oe.gethostid()); catch (ClientException ce) System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message: " + ce.getmessage()); finally /* * Do not forget to shut down the client finally to release all allocated resources. */ client.shutdown(); 20

22 性能测试 /Lite 实践指南 private static File createsamplefile() throws IOException File file = File.createTempFile("oss-java-sdk-", ".txt"); file.deleteonexit(); Writer writer = new OutputStreamWriter(new FileOutputStream(file)); writer.write("abcdefghijklmnopqrstuvwxyz\n"); writer.write(" \n"); writer.close(); return file; private static void displaytextinputstream(inputstream input) throws IOException BufferedReader reader = new BufferedReader(new InputStreamReader(input)); while (true) String line = reader.readline(); if (line == null) break; System.out.println("\t" + line); System.out.println(); reader.close(); 追加文件示例 import java.io.bytearrayinputstream; import java.io.file; import java.io.fileoutputstream; import java.io.ioexception; import java.io.inputstream; import java.io.outputstreamwriter; import java.io.writer; import com.aliyun.oss.clientexception; import com.aliyun.oss.ossclient; import com.aliyun.oss.ossexception; import com.aliyun.oss.model.appendobjectrequest; import com.aliyun.oss.model.appendobjectresult; import com.aliyun.oss.model.ossobject; /** * This sample demonstrates how to upload an object by append mode * to Aliyun OSS using the OSS SDK for Java. */ public class AppendObjectSample private static String endpoint = "*** Provide OSS endpoint ***"; private static String accesskeyid = "*** Provide your AccessKeyId ***"; private static String accesskeysecret = "*** Provide your AccessKeySecret ***"; private static String bucketname = "*** Provide bucket name ***"; 21

23 性能测试 /Lite 实践指南 private static String key = "*** Provide object key ***"; public static void main(string[] args) throws IOException /* * Constructs a client instance with your account for accessing OSS */ OSSClient client = new OSSClient(endpoint, accesskeyid, accesskeysecret); try /* * Append an object from specfied input stream, keep in mind that * position should be set to zero at first time. */ String content = "Thank you for using Aliyun Object Storage Service"; InputStream instream = new ByteArrayInputStream(content.getBytes()); Long firstposition = 0L; System.out.println("Begin to append object at position(" + firstposition + ")"); AppendObjectResult appendobjectresult = client.appendobject( new AppendObjectRequest(bucketName, key, instream).withposition(0l)); System.out.println("\tNext position=" + appendobjectresult.getnextposition() + ", CRC64=" + appendobjectresult.getobjectcrc64() + "\n"); /* * Continue to append the object from specfied file descriptor at last position */ Long nextposition = appendobjectresult.getnextposition(); System.out.println("Continue to append object at last position(" + nextposition + "):"); appendobjectresult = client.appendobject( new AppendObjectRequest(bucketName, key, createtempfile()).withposition(nextposition)); System.out.println("\tNext position=" + appendobjectresult.getnextposition() + ", CRC64=" + appendobjectresult.getobjectcrc64()); /* * View object type of the appendable object */ OSSObject object = client.getobject(bucketname, key); System.out.println("\tObject type=" + object.getobjectmetadata().getobjecttype() + "\n"); // Do not forget to close object input stream if not use it any more object.getobjectcontent().close(); /* * Delete the appendable object */ System.out.println("Deleting an appendable object"); client.deleteobject(bucketname, key); catch (OSSException oe) System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message: " + oe.geterrorcode()); System.out.println("Error Code: " + oe.geterrorcode()); System.out.println("Request ID: " + oe.getrequestid()); System.out.println("Host ID: " + oe.gethostid()); catch (ClientException ce) System.out.println("Caught an ClientException, which means the client encountered " 22

24 性能测试 /Lite 实践指南 + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message: " + ce.getmessage()); finally /* * Do not forget to shut down the client finally to release all allocated resources. */ client.shutdown(); private static File createtempfile() throws IOException File file = File.createTempFile("oss-java-sdk-", ".txt"); file.deleteonexit(); Writer writer = new OutputStreamWriter(new FileOutputStream(file)); writer.write("abcdefghijklmnopqrstuvwxyz\n"); writer.write(" \n"); writer.close(); return file; 分片上传示例 import java.io.file; import java.io.fileinputstream; import java.io.fileoutputstream; import java.io.ioexception; import java.io.inputstream; import java.io.outputstreamwriter; import java.io.writer; import java.util.arraylist; import java.util.collections; import java.util.comparator; import java.util.list; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.timeunit; import com.aliyun.oss.clientexception; import com.aliyun.oss.ossclient; import com.aliyun.oss.ossexception; import com.aliyun.oss.model.completemultipartuploadrequest; import com.aliyun.oss.model.getobjectrequest; import com.aliyun.oss.model.initiatemultipartuploadrequest; import com.aliyun.oss.model.initiatemultipartuploadresult; import com.aliyun.oss.model.listpartsrequest; import com.aliyun.oss.model.partetag; import com.aliyun.oss.model.partlisting; import com.aliyun.oss.model.partsummary; import com.aliyun.oss.model.uploadpartrequest; import com.aliyun.oss.model.uploadpartresult; 23

25 性能测试 /Lite 实践指南 /** * This sample demonstrates how to upload multiparts to Aliyun OSS * using the OSS SDK for Java. */ public class MultipartUploadSample private static String endpoint = "*** Provide OSS endpoint ***"; private static String accesskeyid = "*** Provide your AccessKeyId ***"; private static String accesskeysecret = "*** Provide your AccessKeySecret ***"; private static OSSClient client = null; private static String bucketname = "*** Provide bucket name ***"; private static String key = "*** Provide object key ***"; private static String localfilepath = "*** Provide local file path ***"; private static ExecutorService executorservice = Executors.newFixedThreadPool(5); private static List<PartETag> partetags = Collections.synchronizedList(new ArrayList<PartETag>()); public static void main(string[] args) throws IOException /* * Constructs a client instance with your account for accessing OSS */ client = new OSSClient(endpoint, accesskeyid, accesskeysecret); try /* * Claim a upload id firstly */ String uploadid = claimuploadid(); System.out.println("Claiming a new upload id " + uploadid + "\n"); /* * Calculate how many parts to be divided */ final long partsize = 5 * 1024 * 1024L; // 5MB final File samplefile = createsamplefile(); long filelength = samplefile.length(); int partcount = (int) (filelength / partsize); if (filelength % partsize!= 0) partcount++; if (partcount > 10000) throw new RuntimeException("Total parts count should not exceed 10000"); else System.out.println("Total parts count " + partcount + "\n"); /* * Upload multiparts to your bucket */ System.out.println("Begin to upload multiparts to OSS from a file\n"); for (int i = 0; i < partcount; i++) long startpos = i * partsize; long curpartsize = (i + 1 == partcount)? (filelength - startpos) : partsize; 24

26 性能测试 /Lite 实践指南 executorservice.execute(new PartUploader(sampleFile, startpos, curpartsize, i + 1, uploadid)); /* * Waiting for all parts finished */ executorservice.shutdown(); while (!executorservice.isterminated()) try executorservice.awaittermination(5, TimeUnit.SECONDS); catch (InterruptedException e) e.printstacktrace(); /* * Verify whether all parts are finished */ if (partetags.size()!= partcount) throw new IllegalStateException("Upload multiparts fail due to some parts are not finished yet"); else System.out.println("Succeed to complete multiparts into an object named " + key + "\n"); /* * View all parts uploaded recently */ listallparts(uploadid); /* * Complete to upload multiparts */ completemultipartupload(uploadid); /* * Fetch the object that newly created at the step below. */ System.out.println("Fetching an object"); client.getobject(new GetObjectRequest(bucketName, key), new File(localFilePath)); catch (OSSException oe) System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message: " + oe.geterrorcode()); System.out.println("Error Code: " + oe.geterrorcode()); System.out.println("Request ID: " + oe.getrequestid()); System.out.println("Host ID: " + oe.gethostid()); catch (ClientException ce) System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message: " + ce.getmessage()); finally /* * Do not forget to shut down the client finally to release all allocated resources. */ 25

27 性能测试 /Lite 实践指南 if (client!= null) client.shutdown(); private static class PartUploader implements Runnable private File localfile; private long startpos; private long partsize; private int partnumber; private String uploadid; public PartUploader(File localfile, long startpos, long partsize, int partnumber, String uploadid) this.localfile = localfile; this.startpos = startpos; this.partsize = partsize; this.partnumber = partnumber; this.uploadid = public void run() InputStream instream = null; try instream = new FileInputStream(this.localFile); instream.skip(this.startpos); UploadPartRequest uploadpartrequest = new UploadPartRequest(); uploadpartrequest.setbucketname(bucketname); uploadpartrequest.setkey(key); uploadpartrequest.setuploadid(this.uploadid); uploadpartrequest.setinputstream(instream); uploadpartrequest.setpartsize(this.partsize); uploadpartrequest.setpartnumber(this.partnumber); UploadPartResult uploadpartresult = client.uploadpart(uploadpartrequest); System.out.println("Part#" + this.partnumber + " done\n"); synchronized (partetags) partetags.add(uploadpartresult.getpartetag()); catch (Exception e) e.printstacktrace(); finally if (instream!= null) try instream.close(); catch (IOException e) e.printstacktrace(); 26

28 性能测试 /Lite 实践指南 private static File createsamplefile() throws IOException File file = File.createTempFile("oss-java-sdk-", ".txt"); file.deleteonexit(); Writer writer = new OutputStreamWriter(new FileOutputStream(file)); for (int i = 0; i < ; i++) writer.write("abcdefghijklmnopqrstuvwxyz\n"); writer.write(" \n"); writer.close(); return file; private static String claimuploadid() InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, key); InitiateMultipartUploadResult result = client.initiatemultipartupload(request); return result.getuploadid(); private static void completemultipartupload(string uploadid) // Make part numbers in ascending order Collections.sort(partETags, new public int compare(partetag p1, PartETag p2) return p1.getpartnumber() - p2.getpartnumber(); ); System.out.println("Completing to upload multiparts\n"); CompleteMultipartUploadRequest completemultipartuploadrequest = new CompleteMultipartUploadRequest(bucketName, key, uploadid, partetags); client.completemultipartupload(completemultipartuploadrequest); private static void listallparts(string uploadid) System.out.println("Listing all parts..."); ListPartsRequest listpartsrequest = new ListPartsRequest(bucketName, key, uploadid); PartListing partlisting = client.listparts(listpartsrequest); int partcount = partlisting.getparts().size(); for (int i = 0; i < partcount; i++) PartSummary partsummary = partlisting.getparts().get(i); System.out.println("\tPart#" + partsummary.getpartnumber() + ", ETag=" + partsummary.getetag()); System.out.println(); 27

29 性能测试 /Lite 实践指南 下载文件 简单的下载文件 我们可以通过以下代码将文件读取到一个流中 : // 获取 Object, 返回结果为 OSSObject 对象 OSSObject object = client.getobject(bucketname, key); // 获取 Object Metadata ObjectMetadata metadata = object.getobjectmetadata(); // 获取 Object 的输入流 InputStream objectcontent = object.getobjectcontent(); // 处理 Object... // 关闭流, 请注意, 需要显式关闭, 否则会造成资源泄露 objectcontent.close(); 提示 : OSSObject 实例包含文件所在的存储空间 (Bucket) 文件的名称 Object Metadata 以及一个输入流 通过操作输入流将文件的内容读取到文件或者内存中 而 Object Metadata 包含 ETag HTTP Header 及自定义的元信息 分段读取文件 以下代码展示如何使用 GetObjectRequest#setRange 进行分段读取文件 : // 新建 GetObjectRequest GetObjectRequest getobjectrequest = new GetObjectRequest(bucketName, key); // 获取 0~100 字节范围内的数据 getobjectrequest.setrange(0, 100); // 获取 Object, 返回结果为 OSSObject 对象 OSSObject object = client.getobject(getobjectrequest); 仅获取文件元信息 通过 OSSClient#getObjectMetadata 可以仅获取 ObjectMeta, 而无需获取文件内容 : 28

30 性能测试 /Lite 实践指南 ObjectMetadata metadata = client.getobjectmetadata(bucketname, key); 断点续传下载 当下载大文件时, 如果网络不稳定或者程序崩溃了, 则整个下载就失败了 用户不得不重头再来, 这样做不仅浪费资源, 在网络不稳定的情况下, 往往重试多次还是无法完成下载 通过 OSSClient.downloadFile 接口来实现断点续传分片下载, 参数是 DownloadFileRequest, 该请求有以下参数 : bucket 存储空间名字, 必选参数, 通过构造方法设置 key 下载到 OSS 的 Object 名字, 必选参数, 通过构造方法设置 downloadfile 本地文件, 下载到该文件, 可选参数, 默认是 key, 通过构造方法或 setdownloadfile 设置 partsize 分片大小, 从 1B 到 5GB, 单位是 Byte, 可选参数, 默认 100K, 通过 setpartsize 设置 tasknum 分片下载并发数, 可选参数, 默认为 1, 通过 settasknum 设置 enablecheckpoint 下载是否开启断点续传, 可选参数, 默认断点续传功能关闭, 通过 setenablecheckpoint 设置 checkpointfile 开启断点续传时, 需要在本地记录分片下载结果, 如果下载失败, 下次不会再下载已经成功的分片, 可选参数, 默认与 downloadfile 同目录, 为 downloadfile.ucp, 可以通过 setcheckpointfile 设置 其实现的原理是将要下载的 Object 分成若干个分片分别下载, 最后所有分片都下载成功后, 完成整个文件的下载 在下载的过程中会记录当前下载的进度信息 ( 记录在 checkpoint 文件中 ) 和已下载的分片, 如果下载过程中某一分片下载失败, 再次下载时会从 checkpoint 文件中记录的点继续下载 这要求再次调用时要指定与上次相同的 checkpoint 文件 下载完成后,checkpoint 文件会被删除 DownloadFileRequest downloadfilerequest = new DownloadFileRequest("bucketName", "key"); downloadfilerequest.setdownloadfile("downloadfile"); downloadfilerequest.settasknum(10); downloadfilerequest.setenablecheckpoint(true); DownloadFileResult downloadres = ossclient.downloadfile(downloadfilerequest); 并发下载示例 import java.io.file; import java.io.fileoutputstream; import java.io.ioexception; import java.io.inputstream; import java.io.outputstreamwriter; import java.io.randomaccessfile; import java.io.writer; 29

31 性能测试 /Lite 实践指南 import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.timeunit; import java.util.concurrent.atomic.atomicinteger; import com.aliyun.oss.clientexception; import com.aliyun.oss.ossclient; import com.aliyun.oss.ossexception; import com.aliyun.oss.model.getobjectrequest; import com.aliyun.oss.model.ossobject; import com.aliyun.oss.model.objectmetadata; import com.aliyun.oss.model.putobjectrequest; /** * This sample demonstrates how to download an object concurrently * from Aliyun OSS using the OSS SDK for Java. */ public class ConcurrentGetObjectSample private static String endpoint = "*** Provide OSS endpoint ***"; private static String accesskeyid = "*** Provide your AccessKeyId ***"; private static String accesskeysecret = "*** Provide your AccessKeySecret ***"; private static OSSClient client = null; private static String bucketname = "*** Provide bucket name ***"; private static String key = "*** Provide object key ***"; private static String localfilepath = "*** Provide local file path ***"; private static ExecutorService executorservice = Executors.newFixedThreadPool(5); private static AtomicInteger completedblocks = new AtomicInteger(0); public static void main(string[] args) throws IOException /* * Constructs a client instance with your account for accessing OSS */ client = new OSSClient(endpoint, accesskeyid, accesskeysecret); try /* * Upload an object to your bucket */ System.out.println("Uploading a new object to OSS from a file\n"); client.putobject(new PutObjectRequest(bucketName, key, createsamplefile())); /* * Get size of the object and pre-create a random access file to hold object data */ ObjectMetadata metadata = client.getobjectmetadata(bucketname, key); long objectsize = metadata.getcontentlength(); RandomAccessFile raf = new RandomAccessFile(localFilePath, "rw"); raf.setlength(objectsize); raf.close(); /* * Calculate how many blocks to be divided 30

32 性能测试 /Lite 实践指南 */ final long blocksize = 5 * 1024 * 1024L; // 5MB int blockcount = (int) (objectsize / blocksize); if (objectsize % blocksize!= 0) blockcount++; System.out.println("Total blocks count " + blockcount + "\n"); /* * Download the object concurrently */ System.out.println("Start to download " + key + "\n"); for (int i = 0; i < blockcount; i++) long startpos = i * blocksize; long endpos = (i + 1 == blockcount)? objectsize : (i + 1) * blocksize; executorservice.execute(new BlockFetcher(startPos, endpos, i + 1)); /* * Waiting for all blocks finished */ executorservice.shutdown(); while (!executorservice.isterminated()) try executorservice.awaittermination(5, TimeUnit.SECONDS); catch (InterruptedException e) e.printstacktrace(); /* * Verify whether all blocks are finished */ if (completedblocks.intvalue()!= blockcount) throw new IllegalStateException("Download fails due to some blocks are not finished yet"); else System.out.println("Succeed to download object " + key); catch (OSSException oe) System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message: " + oe.geterrorcode()); System.out.println("Error Code: " + oe.geterrorcode()); System.out.println("Request ID: " + oe.getrequestid()); System.out.println("Host ID: " + oe.gethostid()); catch (ClientException ce) System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message: " + ce.getmessage()); finally /* * Do not forget to shut down the client finally to release all allocated resources. */ if (client!= null) 31

33 性能测试 /Lite 实践指南 client.shutdown(); private static class BlockFetcher implements Runnable private long startpos; private long endpos; private int blocknumber; public BlockFetcher(long startpos, long endpos, int blocknumber) this.startpos = startpos; this.endpos = endpos; this.blocknumber = public void run() RandomAccessFile raf = null; try raf = new RandomAccessFile(localFilePath, "rw"); raf.seek(startpos); OSSObject object = client.getobject(new GetObjectRequest(bucketName, key).withrange(startpos, endpos)); InputStream objectcontent = object.getobjectcontent(); try byte[] buf = new byte[4096]; int bytesread = 0; while ((bytesread = objectcontent.read(buf))!= -1) raf.write(buf, 0, bytesread); completedblocks.incrementandget(); System.out.println("Block#" + blocknumber + " done\n"); catch (IOException e) e.printstacktrace(); finally objectcontent.close(); catch (Exception e) e.printstacktrace(); finally if (raf!= null) try raf.close(); catch (IOException e) e.printstacktrace(); 32

34 性能测试 /Lite 实践指南 private static File createsamplefile() throws IOException File file = File.createTempFile("oss-java-sdk-", ".txt"); file.deleteonexit(); Writer writer = new OutputStreamWriter(new FileOutputStream(file)); for (int i = 0; i < ; i++) writer.write("abcdefghijklmnopqrstuvwxyz\n"); writer.write(" \n"); writer.close(); return file; 管理文件 在 OSS 中, 用户可以通过一系列的接口管理存储空间 (Bucket) 中的文件 (Object), 比如 SetObjectAcl,GetObjectAcl,ListObjects,DeleteObject,CopyObject,DoesObje ctexist 等 Object 的名字又称为 key 或 object key Object 是否存在 通过 OSSClient.doesObjectExist 判断文件是否存在 OSSClient client = new OSSClient("<endpoint>", "<accesskeyid>", "<accesskeysecret>"); boolean found = client.doesobjectexist("<bucketname>", "<key>") Object ACL 设置 Object ACL OSS 不仅可以设置 Bucket ACL, 也可以设置 Object ACL 设置 Object ACL 注意事项 : 如果没有设置 Object 的权限, 即 Object 的 ACL 为 default,object 的权限和 Bucket 权限一致 如果设置了 Object 的权限,Object 的权限大于 Bucket 权限 举个例子, 如果设置了 Object 的权限是 public-read, 无论 Bucket 是什么权限, 该 Object 都可以被身份验证访问和匿名访问 下面代码为 Object 设置 ACL: 33

35 性能测试 /Lite 实践指南 private static final CannedAccessControlList[] ACLS = CannedAccessControlList.Private, CannedAccessControlList.PublicRead, CannedAccessControlList.PublicReadWrite, CannedAccessControlList.Default ; // 上传文件 final String key = "normal-set-object-acl"; final long inputstreamlength = 128 * 1024; //128KB InputStream instream = genfixedlengthinputstream(inputstreamlength); client.putobject(bucketname, key, instream, null); // 设置 Object ACL for (CannedAccessControlList acl : ACLS) client.setobjectacl(bucketname, key, acl); 获取 Object ACL // 读取 Object ACL ObjectAcl returnedacl = client.getobjectacl("<bucketname>", "<key>"); System.out.println(returnedAcl.getPermission().toString()); 查看文件的 meta 查看文件的 meta 可以使用 getsimplifiedobjectmeta 或 getobjectmetadata getsimplifiedobjectmeta 只能获取文件的 ETag Size( 文件大小 ) LastModified( 最后修改时间 ); getobjectmetadata 可以获取文件的全部 meta getsimplifiedobjectmeta 更轻量 更快 OSSClient client = new OSSClient("<endpoint>", "<accesskeyid>", "<accesskeysecret>"); SimplifiedObjectMeta objectmeta = client.getsimplifiedobjectmeta("<bucketname>", "<key>"); System.out.println(objectMeta.getSize()); System.out.println(objectMeta.getETag()); System.out.println(objectMeta.getLastModified()); ObjectMetadata metadata = client.getobjectmetadata("<bucketname>", "<key>"); System.out.println(metadata.getContentType()); System.out.println(metadata.getLastModified()); System.out.println(metadata.getExpirationTime()); 列出存储空间中的文件 可以通过 OSSClient.listObjects 列出 bucket 里的 Objects listobjects 有三类参数格式 : listobjects(string bucketname) 34

36 性能测试 /Lite 实践指南 listobjects(string bucketname, String prefix) listobjects(listobjectsrequest listobjectsrequest) 前两类称为简单列举, 最多返回 100 条 object, 参数 prefix 是指定返回 Object 的前缀 最后一类提供多种过滤功能, 可以实现灵活的查询功能 提示 : listobjects 的完整代码请参考 :GitHub 简单列举 列举出 Bucket 下的 Object, 最多 100 条 object OSSClient client = new OSSClient("<endpoint>", "<accesskeyid>", "<accesskeysecret>"); ObjectListing objectlisting = client.listobjects("<bucketname>", "<KeyPrifex>"); List<OSSObjectSummary> sums = objectlisting.getobjectsummaries(); for (OSSObjectSummary s : sums) System.out.println("\t" + s.getkey()); 列举出 Bucket 下的指定前缀的 Object, 最多 100 条 object OSSClient client = new OSSClient("<endpoint>", "<accesskeyid>", "<accesskeysecret>"); ObjectListing objectlisting = client.listobjects("<bucketname>", "<KeyPrifex>"); List<OSSObjectSummary> sums = objectlisting.getobjectsummaries(); for (OSSObjectSummary s : sums) System.out.println("\t" + s.getkey()); 通过 ListObjectsRequest 列出文件 listobjects 的参数是 ListObjectsRequest 时, 可以通过设置 ListObjectsReques 的参数实现各种灵活的查询功能 ListObjectsReques 的参数和作用如下 : 名称 作用 Delimiter 用于对文件名字进行分组的字符 所有名字包含指定的前缀且第一次出现 Delimiter 字 CommonPrefixes Marker 设定结果从 Marker 之后按字母排序的第一个开始返回 MaxKeys 限定此次返回文件的最大数, 如果不设定, 默认为 100,MaxKeys 取值不能大于 1000 EncodingType 请求响应体中 Object 名称采用的编码方式, 目前支持 url 指定最大返回条数 OSSClient client = new OSSClient("<endpoint>", "<accesskeyid>", "<accesskeysecret>"); final int maxkeys = 30; 35

37 性能测试 /Lite 实践指南 ObjectListing objectlisting = client.listobjects(new ListObjectsRequest("<bucketName>").withMaxKeys(maxKeys)); List<OSSObjectSummary> sums = objectlisting.getobjectsummaries(); for (OSSObjectSummary s : sums) System.out.println("\t" + s.getkey()); 只返回指定前缀的 object 最多返回 100 条 final String keyprefix = "<keyprefix>" ObjectListing objectlisting = client.listobjects(new ListObjectsRequest("<bucketName>").withPrefix(keyPrefix)); List<OSSObjectSummary> sums = objectlisting.getobjectsummaries(); for (OSSObjectSummary s : sums) System.out.println("\t" + s.getkey()); 从指定某 Object 后返回 最多返回 100 条 final String keymarker = "<keymarker>" ObjectListing objectlisting = client.listobjects(new ListObjectsRequest("<bucketName>").withMarker(keyMarker)); List<OSSObjectSummary> sums = objectlisting.getobjectsummaries(); for (OSSObjectSummary s : sums) System.out.println("\t" + s.getkey()); 分页获取所有 Object 分页获取所有 Object, 每页 maxkeys 条 Object final int maxkeys = 30; String nextmarker = null; do objectlisting = client.listobjects(new ListObjectsRequest("<bucketName>").withMarker(nextMarker).withMaxKeys(maxKeys)); List<OSSObjectSummary> sums = objectlisting.getobjectsummaries(); for (OSSObjectSummary s : sums) System.out.println("\t" + s.getkey()); 36

38 性能测试 /Lite 实践指南 nextmarker = objectlisting.getnextmarker(); while (objectlisting.istruncated()); 分页获取所有特定 Object 后的 Object 分页获取所有特定 Object 后的 Object, 每页 maxkeys 条 Object final int maxkeys = 30; String nextmarker = "<nextmarker>"; do objectlisting = client.listobjects(new ListObjectsRequest("<bucketName>").withMarker(nextMarker).withMaxKeys(maxKeys)); List<OSSObjectSummary> sums = objectlisting.getobjectsummaries(); for (OSSObjectSummary s : sums) System.out.println("\t" + s.getkey()); nextmarker = objectlisting.getnextmarker(); while (objectlisting.istruncated()); 分页所有获取指定前缀的 Object 分页所有获取指定前缀的 Object, 每页 maxkeys 条 Object final int maxkeys = 30; final String keyprefix = "<keyprefix>"; String nextmarker = "<nextmarker>"; do objectlisting = client.listobjects(new ListObjectsRequest("<bucketName>"). withprefix(keyprefix).withmarker(nextmarker).withmaxkeys(maxkeys)); List<OSSObjectSummary> sums = objectlisting.getobjectsummaries(); for (OSSObjectSummary s : sums) System.out.println("\t" + s.getkey()); nextmarker = objectlisting.getnextmarker(); while (objectlisting.istruncated()); 文件夹功能模拟 可以通过 Delimiter 和 Prefix 参数的配合模拟出文件夹功能, 将 Prefix 设为某个文件夹名, 就可以罗列以此 Prefix 开头的文件, 即该文件夹下递归的所有的文件和子文件夹 如果再把 Delimiter 设置为 "/" 时, 返回值就只罗列该文件夹下的文件, 该文件夹下的子文件夹返回在 CommonPrefixes 部分, 子文件夹下递归的文件和文件夹不被显示. 假设 37

39 阿里云大数据平台 / 机器翻译 Bucket 中有 4 个文件 : oss.jpg, fun/test.jpg, fun/movie/001.avi, fun/movie/007.avi, 我们把 "/" 符号作为文件夹的分隔符 提示 : 创建文件的完整代码请参考 :GitHub 列出存储空间内所有文件 当我们需要获取存储空间下的所有文件时, 可以这样写 : // 构造 ListObjectsRequest 请求 ListObjectsRequest listobjectsrequest = new ListObjectsRequest(bucketName); // List Objects ObjectListing listing = client.listobjects(listobjectsrequest); // 遍历所有 Object System.out.println("Objects:"); for (OSSObjectSummary objectsummary : listing.getobjectsummaries()) System.out.println(objectSummary.getKey()); // 遍历所有 CommonPrefix System.out.println("CommonPrefixs:"); for (String commonprefix : listing.getcommonprefixes()) System.out.println(commonPrefix); 输出 : Objects: fun/movie/001.avi fun/movie/007.avi fun/test.jpg oss.jpg CommonPrefixs: 递归列出目录下所有文件 我们可以通过设置 Prefix 参数来获取某个目录下所有的文件 : // 构造 ListObjectsRequest 请求 ListObjectsRequest listobjectsrequest = new ListObjectsRequest(bucketName); // 递归列出 fun 目录下的所有文件 listobjectsrequest.setprefix("fun/"); 38

40 阿里云大数据平台 / 机器翻译 ObjectListing listing = client.listobjects(listobjectsrequest); // 遍历所有 Object System.out.println("Objects:"); for (OSSObjectSummary objectsummary : listing.getobjectsummaries()) System.out.println(objectSummary.getKey()); // 遍历所有 CommonPrefix System.out.println("\nCommonPrefixs:"); for (String commonprefix : listing.getcommonprefixes()) System.out.println(commonPrefix); 输出 : Objects: fun/movie/001.avi fun/movie/007.avi fun/test.jpg CommonPrefixs: 列出目录下的文件和子目录 在 Prefix 和 Delimiter 结合的情况下, 可以列出目录下的文件和子目录 : // 构造 ListObjectsRequest 请求 ListObjectsRequest listobjectsrequest = new ListObjectsRequest(bucketName); // "/" 为文件夹的分隔符 listobjectsrequest.setdelimiter("/"); // 列出 fun 目录下的所有文件和文件夹 listobjectsrequest.setprefix("fun/"); ObjectListing listing = client.listobjects(listobjectsrequest); // 遍历所有 Object System.out.println("Objects:"); for (OSSObjectSummary objectsummary : listing.getobjectsummaries()) System.out.println(objectSummary.getKey()); // 遍历所有 CommonPrefix System.out.println("\nCommonPrefixs:"); for (String commonprefix : listing.getcommonprefixes()) System.out.println(commonPrefix); 输出 : 39

41 开放数据处理服务 ODPS/SDK Objects: fun/test.jpg CommonPrefixs: fun/movie/ 提示 : 返回的结果中, ObjectSummaries 的列表中给出的是 fun 目录下的文件 而 CommonPrefixs 的列表中给出的是 fun 目录下的所有子文件夹 可以看出 fun/movie/001.avi, fun/movie/007.avi 两个文件并没有被列出来, 因为它们属于 fun 文件夹下的 movie 目录 删除文件 删除一个文件 : client.deleteobject(bucketname, key); 删除多个文件 : 提示 : 批量删除文件的完整代码请参考 :GitHub List<String> keys = new ArrayList<String>(); keys.add("key0"); keys.add("key1"); keys.add("key2"); DeleteObjectsResult deleteobjectsresult = client.deleteobjects( new DeleteObjectsRequest(bucketName).withKeys(keys)); List<String> deletedobjects = deleteobjectsresult.getdeletedobjects(); 拷贝文件 在同一个区域 ( 杭州, 深圳, 青岛等 ) 中, 用户可以对有操作权限的文件进行复制操作 拷贝一个文件 通过 copyobject 方法我们可以拷贝一个文件, 代码如下 : // 拷贝 Object 40

42 开放数据处理服务 ODPS/SDK CopyObjectResult result = client.copyobject(srcbucketname, srckey, destbucketname, destkey); // 打印结果 System.out.println("ETag: " + result.getetag() + " LastModified: " + result.getlastmodified()); 注意 : 使用该方法拷贝的文件必须小于 1G, 否则会报错 若文件大于 1G, 使用下面的 Upload Part Copy 通过 CopyObjectRequest 拷贝 Object 也可以通过 CopyObjectRequest 实现 Object 的拷贝 : // 创建 CopyObjectRequest 对象 CopyObjectRequest copyobjectrequest = new CopyObjectRequest(srcBucketName, srckey, destbucketname, destkey); // 设置新的 Metadata ObjectMetadata meta = new ObjectMetadata(); meta.setcontenttype("text/html"); copyobjectrequest.setnewobjectmetadata(meta); // 复制 Object CopyObjectResult result = client.copyobject(copyobjectrequest); System.out.println("ETag: " + result.getetag() + " LastModified: " + result.getlastmodified()); 提示 : CopyObjectRequest 允许用户修改目的 Object 的 ObjectMeta, 同时也提供 ModifiedSinceConstraint, UnmodifiedSinceConstraint,MatchingETagConstraints, NonmatchingEtagConstraints 四个参数的设定, 用法与 GetObjectRequest 的参数相似, 参见 GetObjectRequest 的可设置参数 可以通过拷贝操作来实现修改已有 Object 的 meta 信息 如果拷贝操作的源 Object 地址和目标 Object 地址相同, 则直接替换源 Object 的 meta 信息 拷贝大文件 Upload Part Copy 拷贝上传 Upload Part Copy 通过从一个已经存在的 object 中拷贝数据来上传一个 object 当拷贝一个大于 500MB 的文件, 建议使用 Upload Part Copy 的方式来进行拷贝 41

43 开放数据处理服务 ODPS/SDK 提示 : 分片拷贝的完整代码请参考 :GitHub ObjectMetadata objectmetadata = client.getobjectmetadata(sourcebucketname,sourcekey); long partsize = 1024 * 1024 * 100; // 得到被拷贝 object 大小 long contentlength = objectmetadata.getcontentlength(); // 计算分块数目 int partcount = (int) (contentlength / partsize); if (contentlength % partsize!= 0) partcount++; System.out.println("total part count:" + partcount); List<PartETag> partetags = new ArrayList<PartETag>(); long starttime = System.currentTimeMillis(); for (int i = 0; i < partcount; i++) System.out.println("now begin to copy part:" + (i+1)); long skipbytes = partsize * i; // 计算每个分块的大小 long size = partsize < contentlength - skipbytes? partsize : contentlength - skipbytes; // 创建 UploadPartCopyRequest, 上传分块 UploadPartCopyRequest uploadpartcopyrequest = new UploadPartCopyRequest(sourceBucketName, sourcekey, targetbucketname, targetkey); uploadpartcopyrequest.setuploadid(uploadid); uploadpartcopyrequest.setpartsize(size); uploadpartcopyrequest.setbeginindex(skipbytes); uploadpartcopyrequest.setpartnumber(i + 1); UploadPartCopyResult uploadpartcopyresult = client.uploadpartcopy(uploadpartcopyrequest); // 将返回的 PartETag 保存到 List 中 partetags.add(uploadpartcopyresult.getpartetag()); System.out.println("now end to copy part:" + (i+1)); 以上程序调用 uploadpartcopy 方法来拷贝每一个分块 与 UploadPart 要求基本一致, 需要通过 setbeginindex 来定位到此次上传块开头所对应的位置, 同时需要通过 setsourcekey 来指定 copy 的 object 授权访问 使用 STS 服务临时授权 介绍 OSS 可以通过阿里云 STS 服务, 临时进行授权访问 阿里云 STS (Security Token Service) 是为云计算用户提供临时访问令牌的 Web 服务 通过 STS, 您可以为第三方应用或联邦用 42

44 开放数据处理服务 ODPS/SDK 户 ( 用户身份由您自己管理 ) 颁发一个自定义时效和权限的访问凭证 第三方应用或联邦用户可以使用该访问凭证直接调用阿里云产品 API, 或者使用阿里云产品提供的 SDK 来访问云产品 API 您不需要透露您的长期密钥 (AccessKey) 给第三方应用, 只需要生成一个访问令牌并将令牌交给第三方应用即可 这个令牌的访问权限及有效期限都可以由您自定义 您不需要关心权限撤销问题, 访问令牌过期后就自动失效 以 APP 应用为例, 交互流程如下图 : 方案的详细描述如下 : App 用户登录 App 用户身份是客户自己管理 客户可以自定义身份管理系统, 也可以使用外部 Web 账号或 OpenID 对于每个有效的 App 用户来说,AppServer 是可以确切地定义出每个 App 用户的最小访问权限 AppServer 请求 STS 服务获取一个安全令牌 (SecurityToken) 在调用 STS 之前,AppServer 需要确定 App 用户的最小访问权限 ( 用 Policy 语法描述 ) 以及授权的过期时间 然后通过调用 STS 的 AssumeRole( 扮演角色 ) 接口来获取安全令牌 角色管理与使用相关内容请参考 RAM 使用指南 中的角色管理 STS 返回给 AppServer 一个有效的访问凭证, 包括一个安全令牌 (SecurityToken) 临时访问密钥 (AccessKeyId, AccessKeySecret) 以及过期时间 AppServer 将访问凭证返回给 ClientApp ClientApp 可以缓存这个凭证 当凭证失效时,ClientApp 需要向 AppServer 申请新的有效访问凭证 比如, 访问凭证有效期为 1 小时, 那么 ClientApp 可以每 30 分钟向 AppServer 请求更新访问凭证 ClientApp 使用本地缓存的访问凭证去请求 Aliyun Service API 云服务会感知 STS 访问凭证, 并会依赖 STS 服务来验证访问凭证, 并正确响应用户请求 STS 安全令牌详情, 请参考 RAM 使用指南 中的角色管理 关键是调用 STS 服务接口 AssumeRole 来获取有效访问凭证即可 也可以直接使用 STS SDK 来调用该方法, 点击查看 使用 STS 凭证构造签名请求 用户的 client 端拿到 STS 临时凭证后, 通过其中安全令牌 (SecurityToken) 以及临时访问密 43

45 开放数据处理服务 ODPS/SDK 钥 (AccessKeyId, AccessKeySecret) 生成 OSSClient 以上传 Object 为例 : String accesskeyid = "<accesskeyid>"; String accesskeysecret = "<accesskeysecret>"; String securitytoken = "<securitytoken>" // 以杭州为例 String endpoint = " OSSClient client = new OSSClient(endpoint, accesskeyid, accesskeysecret, securitytoken); 使用 URL 签名授权访问 生成签名 URL 通过生成签名 URL 的形式提供给用户一个临时的访问 URL 在生成 URL 时, 您可以指定 URL 过期的时间, 从而限制用户长时间访问 生成一个签名的 URL 代码如下 : String bucketname = "your-bucket-name"; String key = "your-object-key"; // 设置 URL 过期时间为 1 小时 Date expiration = new Date(new Date().getTime() * 1000); // 生成 URL URL url = client.generatepresignedurl(bucketname, key, expiration); 生成的 URL 默认以 GET 方式访问, 这样, 用户可以直接通过浏览器访问相关内容 生成其他 Http 方法的 URL 如果您想允许用户临时进行其他操作 ( 比如上传, 删除 Object), 可能需要签名其他方法的 URL, 如下 : // 生成 PUT 方法的 URL URL url = client.generatepresignedurl(bucketname, key, expiration, HttpMethod.PUT); 通过传入 HttpMethod.PUT 参数, 用户可以使用生成的 URL 上传 Object 添加用户自定义参数 (UserMetadata) 如果您想生成签名的 URL 来上传 Object, 并指定 UserMetadata,Content-Type 等头信息, 可以这样做 : 44

46 开放数据处理服务 ODPS/SDK // 创建请求 GeneratePresignedUrlRequest generatepresignedurlrequest = new GeneratePresignedUrlRequest(bucketName, key); // HttpMethod 为 PUT generatepresignedurlrequest.setmethod(httpmethod.put); // 添加 UserMetadata generatepresignedurlrequest.addusermetadata("author", "baymax"); // 添加 Content-Type request.setcontenttype("application/octet-stream"); // 生成签名的 URL URL url = client.generatepresignedurl(generatepresignedurlrequest); 需要注意的是, 上述过程只是生成了签名的 URL, 您仍需要在 request header 中添加 meta 的信息 可以参考下面的代码 使用签名 URL 发送请求 现在 java SDK 支持 put object 和 get object 两种方式的 URL 签名请求 使用 URL 签名的方式 getobject // 服务器端生成 url 签名字串 OSSClient Server = new OSSClient(endpoint, accessid, accesskey); Date expiration = DateUtil.parseRfc822Date("Wed, 18 Mar :20:00 GMT"); GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key, HttpMethod.GET); // 设置过期时间 request.setexpiration(expiration); // 生成 URL 签名 (HTTP GET 请求 ) URL signedurl = Server.generatePresignedUrl(request); System.out.println("signed url for getobject: " + signedurl); // 客户端使用使用 url 签名字串发送请求 OSSClient client = new OSSClient(endpoint, accesskeyid, accesskeysecret); Map<String, String> customheaders = new HashMap<String, String>(); // 添加 GetObject 请求头 customheaders.put("range", "bytes= "); OSSObject object = client.getobject(signedurl,customheaders); 使用 URL 签名的方式 putobject // 服务器端生成 url 签名字串 OSSClient Server = new OSSClient(endpoint, accesskeyid, accesskeysecret); Date expiration = DateUtil.parseRfc822Date("Wed, 18 Mar :20:00 GMT"); GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key, HttpMethod.PUT); 45

47 开放数据处理服务 ODPS/SDK // 设置过期时间 request.setexpiration(expiration); // 设置 Content-Type request.setcontenttype("application/octet-stream"); // 添加 user meta request.addusermetadata("author", "aliy"); // 生成 URL 签名 (HTTP PUT 请求 ) URL signedurl = Server.generatePresignedUrl(request); System.out.println("signed url for putobject: " + signedurl); // 客户端使用使用 url 签名字串发送请求 OSSClient client = new OSSClient(endpoint, accesskeyid, accesskeysecret); File f = new File(filePath); FileInputStream fin = new FileInputStream(f); // 添加 PutObject 请求头 Map<String, String> customheaders = new HashMap<String, String>(); customheaders.put("content-type", "application/octet-stream"); // 添加 user meta customheaders.put("x-oss-meta-author", "aliy"); PutObjectResult result = client.putobject(signedurl, fin, f.length(), customheaders); # 生命周期管理 (Lifecycle) OSS 允许用户对 Bucket 设置生命周期规则, 以自动淘汰过期掉的文件, 节省存储空间 针对不同前缀的文件, 用户可以同时设置多条规则 一条规则包含 : 规则 ID, 用于标识一条规则, 不能重复 受影响的文件前缀, 此规则只作用于符合前缀的文件 过期时间, 有三种指定方式 : 1. 指定距文件最后修改时间 N 天过期 2. 指定日期创建前的文件过期, 之后的不过期 3. 指定在具体的某一天过期, 即在那天之后符合前缀的文件将会过期, 而不论文件的最后修改时间 不推荐使用 是否生效 上面的过期规则对用户上传的文件有效 用户通过 uploadpart 上传的分片, 也可以设置过期规则 Multipart 的 Lifecycle 和文件的类似, 过期时间支持 1 2 两种, 不支持 3, 生效是以 init Multipart upload 的时间为准 更多关于生命周期的内容请参考文件生命周期 设置生命周期规则 通过 OSSClient.setBucketLifecycle 来设置生命周期规则 : SetBucketLifecycleRequest request = new SetBucketLifecycleRequest("bucketName"); // 最近修改 3 天后过期 request.addlifecyclerule(new LifecycleRule(ruleId0, matchprefix0, RuleStatus.Enabled, 3)); 46

48 // 特定日期后过期 request.addlifecyclerule(new LifecycleRule(ruleId1, matchprefix1, RuleStatus.Enabled, DateUtil.parseIso8601Date(" T00:00:00.000Z"))); // 特定日期前创建的文件过期 LifecycleRule rule = new LifecycleRule(ruleId4, matchprefix4, RuleStatus.Enabled); rule.setcreatedbeforedate(dateutil.parseiso8601date(" t00:00:00.000z")); request.addlifecyclerule(rule); // Multipart3 天后过期 rule = new LifecycleRule(ruleId2, matchprefix2, RuleStatus.Enabled); LifecycleRule.AbortMultipartUpload abortmultipartupload = rule.new AbortMultipartUpload(); abortmultipartupload.setexpirationdays(3); rule.setabortmultipartupload(abortmultipartupload); request.addlifecyclerule(rule); // 特定日期前的 Multipart 过期 rule = new LifecycleRule(ruleId3, matchprefix3, RuleStatus.Enabled); abortmultipartupload = rule.new AbortMultipartUpload(); abortmultipartupload.setcreatedbeforedate(dateutil.parseiso8601date(" t00:00:00.000z")); rule.setabortmultipartupload(abortmultipartupload); request.addlifecyclerule(rule); ossclient.setbucketlifecycle(request); 查看生命周期规则 通过 OSSClient.GetBucketLifecycle 来查看生命周期规则 : List<LifecycleRule> rules = ossclient.getbucketlifecycle("bucketname"); for (LifecycleRule rule : rules) System.out.println(rule.getId()); System.out.println(rule.getPrefix()); System.out.println(rule.getExpirationDays()); 清空生命周期规则 通过 OSSClient.DeleteBucketLifecycle 设置来清空生命周期规则 : ossclient.deletebucketlifecycle("bucketname"); 跨域资源共享设置 跨域资源共享 (CORS) 允许 web 端的应用程序访问不属于本域的资源 OSS 提供接口方便开发者控制跨域访问的权限 47

49 设定 CORS 规则 通过 setbucketcors 方法将指定的存储空间上设定一个跨域资源共享 CORS 的规则, 如果原规则存在则覆盖原规则 具体的规则主要通过 CORSRule 类来进行参数设置 代码如下 : SetBucketCORSRequest request = new SetBucketCORSRequest(); request.setbucketname(bucketname); //CORS 规则的容器, 每个 bucket 最多允许 10 条规则 ArrayList<CORSRule> putcorsrules = new ArrayList<CORSRule>(); CORSRule corrule = new CORSRule(); ArrayList<String> allowedorigin = new ArrayList<String>(); // 指定允许跨域请求的来源 allowedorigin.add( " ArrayList<String> allowedmethod = new ArrayList<String>(); // 指定允许的跨域请求方法 (GET/PUT/DELETE/POST/HEAD) allowedmethod.add("get"); ArrayList<String> allowedheader = new ArrayList<String>(); // 控制在 OPTIONS 预取指令中 Access-Control-Request-Headers 头中指定的 header 是否允许 allowedheader.add("x-oss-test"); ArrayList<String> exposedheader = new ArrayList<String>(); // 指定允许用户从应用程序中访问的响应头 exposedheader.add("x-oss-test1"); corrule.setallowedmethods(allowedmethod); corrule.setallowedorigins(allowedorigin); corrule.setallowedheaders(allowedheader); corrule.setexposeheaders(exposedheader); // 指定浏览器对特定资源的预取 (OPTIONS) 请求返回结果的缓存时间, 单位为秒 corrule.setmaxageseconds(10); // 最多允许 10 条规则 putcorsrules.add(corrule); request.setcorsrules(putcorsrules); oss.setbucketcors(request); 提示 : 每个存储空间最多只能使用 10 条规则 AllowedOrigins 和 AllowedMethods 都能够最多支持一个 "*" 通配符 "*" 表示对于所有的域来源或者操作都满足 而 AllowedHeaders 和 ExposeHeaders 不支持通配符 48

50 获取 CORS 规则 我们可以参考存储空间的 CORS 规则, 通过 GetBucketCors 方法 代码如下 : ArrayList<CORSRule> corsrules; // 获得 CORS 规则列表 corsrules = (ArrayList<CORSRule>) oss.getbucketcorsrules(bucketname); for (CORSRule rule : corsrules) for (String allowedorigin1 : rule.getallowedorigins()) // 获得允许跨域请求源 System.out.println(allowedOrigin1); for (String allowedmethod1 : rule.getallowedmethods()) // 获得允许跨域请求方法 System.out.println(allowedMethod1); if (rule.getallowedheaders().size() > 0) for (String allowedheader1 : rule.getallowedheaders()) // 获得允许头部列表 System.out.println(allowedHeader1); if (rule.getexposeheaders().size() > 0) for (String exposeheader : rule.getexposeheaders()) // 获得允许头部 System.out.println(exposeHeader); if ( null!= rule.getmaxageseconds()) System.out.println(rule.getMaxAgeSeconds()); 删除 CORS 规则 用于关闭指定存储空间对应的 CORS 并清空所有规则 // 清空 bucket 的 CORS 规则 oss.deletebucketcorsrules(bucketname); 设置访问日志 (Logging) OSS 允许用户对 Bucket 设置访问日志记录, 设置之后对于 Bucket 的访问会被记录成日志, 日志存储在 OSS 上由用户指定的 Bucket 中, 文件的格式为 : 49

51 <TargetPrefix><SourceBucket>-YYYY-mm-DD-HH-MM-SS-UniqueString 其中 TargetPrefix 由用户指定 日志规则由以下 2 项组成 : target_bucket, 存放日志文件的 Bucket target_prefix, 保存访问日志文件前缀 更多关于访问日志的内容请参考 Bucket 访问日志 开启 Bucket 日志 通过 OSSClient.setBucketLogging 来开启日志功能 : SetBucketLoggingRequest request = new SetBucketLoggingRequest("sourceBucket"); request.settargetbucket("targetbucket"); request.settargetprefix("targetprefix"); ossclient.setbucketlogging(request); 查看 Bucket 日志设置 通过 OSSClient.getBucketLogging 来查看日志设置 : BucketLoggingResult result = ossclient.getbucketlogging("sourcebucket"); System.out.println(result.getTargetBucket()); System.out.println(result.getTargetPrefix()); 关闭 Bucket 日志 通过 OSSClient.setBucketLogging 来关闭日志功能 : SetBucketLoggingRequest request = new SetBucketLoggingRequest("sourceBucket"); request.settargetbucket(null); request.settargetprefix(null); ossclient.setbucketlogging(request); 托管静态网站 在 [ 自定义域名绑定 ] 中提到,OSS 允许用户将自己的域名指向 OSS 服务的地址 这样用户访问他的网站的时候, 实际上是在访问 OSS 的 Bucket 对于网站, 需要指定首页 (index) 和出错页 (error) 分别对应的 Bucket 中的文件名 50

52 更多关于静态网站托管的内容请参考 OSS 静态网站托管 设置托管页面 通过 OSSClient.setBucketWebsite 来设置托管页面 : SetBucketWebsiteRequest request = new SetBucketWebsiteRequest("bucketName"); request.setindexdocument("index.html"); request.seterrordocument("error.html"); ossclient.setbucketwebsite(request); 查看托管页面 通过 OSSClient.getBucketWebsite 来查看托管页面 : BucketWebsiteResult result = ossclient.getbucketwebsite("bucketname"); System.out.println(result.getIndexDocument()); System.out.println(result.getErrorDocument()); 清除托管页面 通过 OSSClient.deleteBucketWebsite 来清除托管页面 : ossclient.deletebucketwebsite("bucketname"); 防盗链设置 OSS 是按使用收费的服务, 为了防止用户在 OSS 上的数据被其他人盗链,OSS 支持基于 HTTP header 中表头字段 referer 的防盗链方法 设置 Referer 白名单 通过下面代码设置 Referer 白名单 : OSSClient client = new OSSClient(endpoint, accessid, accesskey); List<String> refererlist = new ArrayList<String>(); // 添加 referer 项 refererlist.add(" refererlist.add(" refererlist.add(" 51

53 // 允许 referer 字段为空, 并设置 Bucket Referer 列表 BucketReferer br = new BucketReferer(true, refererlist); client.setbucketreferer(bucketname, br); 注意 : Referer 参数支持通配符 "*" 和 "?", 更多详细的规则配置可以参考开发人员指南 OSS 防盗链 获取 Referer 白名单 // 获取 Bucket Referer 列表 br = client.getbucketreferer(bucketname); refererlist = br.getrefererlist(); for (String referer : refererlist) System.out.println(referer); 输出结果示例 : 清空 Referer 白名单 Referer 白名单不能直接清空, 只能通过重新设置来覆盖之前的规则 OSSClient client = new OSSClient(endpoint, accessid, accesskey); // 默认允许 referer 字段为空, 且 referer 白名单为空 BucketReferer br = new BucketReferer(); client.setbucketreferer(bucketname, br); 跨区域复制 (Replication) 跨区域复制是跨不同 OSS 数据中心的 Bucket 自动 异步地复制 Object, 它会将对源 Bucket 中的对象的改动 ( 新建 覆盖 删除等 ) 同步到目标 Bucket 该功能能够很好的提供 Bucket 跨区域容灾或满足用户数据复制的需求 目标 Bucket 中的对象是源 Bucket 中对象的精确副本, 它们具有相同的对象名 元数据以及内容 ( 例如, 创建时间 拥有者 用户定义的元数据 Object ACL 对象内容等 ) 更多跨区域复制的内容请参考跨区域复制 52

54 开启跨区域复制 通过 OSSClient.addBucketReplication 开启跨区域复制 : AddBucketReplicationRequest request = new AddBucketReplicationRequest("bucketName"); request.setreplicationruleid("ruleid"); request.settargetbucketname("targetbucketname"); request.settargetbucketlocation("oss-cn-qingdao"); ossclient.addbucketreplication(request); 提示 : 开启跨区域复制, 默认会同步历史数据 如果不需要同步历史数据, 使用 AddBucketReplicationRequest.setEnableHistoricalObjectReplication( false) 禁止历史数据同步 查看跨区域复制 通过 OSSClient.getBucketReplication 查看 bucket 上开启的跨区域复制 : List<ReplicationRule> rules = ossclient.getbucketreplication("bucketname"); for (ReplicationRule rule : rules) System.out.println(rule.getReplicationRuleID()); System.out.println(rule.getTargetBucketLocation()); System.out.println(rule.getTargetBucketName()); 删除跨区域复制 通过 OSSClient.deleteBucketReplication 删除已开启的跨区域复制, 删除后目标 bucket 和 object 依然存在 : ossclient.deletebucketreplication("bucketname", "ruleid"); 查看跨区域复制进度 复制进度分为历史数据同步进度 实时数据同步进度 历史数据的同步用百分比表示, 如 0.80 表示完成了 80%, 仅对开启了历史数据同步的 Bucket 有效 实时数据同步用新写入数据的时间点表示, 表示这个时间点之前的数据已同步完成 通过 OSSClient.deleteBucketReplication 查看跨区域复制进度 : 53

55 BucketReplicationProgress process = ossclient.getbucketreplicationprogress("bucketname", "repruleid"); System.out.println(process.getReplicationRuleID()); // 是否开启了历史数据同步 System.out.println(process.isEnableHistoricalObjectReplication()); // 历史数据同步进度 System.out.println(process.getHistoricalObjectProgress()); // 实时数据同步进度 System.out.println(process.getNewObjectProgress()); 查看目标数据中心 通过 OSSClient.getBucketReplicationLocation 获取 Bucket 所在的数据中心可同步到的数据中心 : List<String> locations = ossclient.getbucketreplicationlocation("bucketname"); for (String loc : locations) System.out.println(loc); 异常处理 OSS Java SDK 包含两类异常, 一类是服务器端异常 OSSException, 另一类是客户端异常 ClientException, 它们均继承自 RuntimeException 调用 OSSClient 类的相关接口时, 如果抛出 OSSException 或者 ClientException, 则表明操作失败, 否则操作成功 异常处理示例 try // Do some operations with the instance here, such as put object... client.putobject(...); catch (OSSException oe) System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message: " + oe.geterrorcode()); System.out.println("Error Code: " + oe.geterrorcode()); System.out.println("Request ID: " + oe.getrequestid()); System.out.println("Host ID: " + oe.gethostid()); catch (ClientException ce) System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message: " + ce.getmessage()); finally if (client!= null) client.shutdown(); 54

56 ClientException ClientException 表示客户端尝试向 OSS 发送请求以及数据传输时遇到的异常 例如, 当发送请求时网络连接不可用时, 则会抛出 ClientException; 当上传文件时发生 IO 异常时, 也会抛出 ClientException OSSException OSSException 指服务器端错误, 它来自于对服务器错误信息的解析, 包含 OSS 会返回给用户相应的错误码和错误信息, 便于用户定位问题, 并做出适当的处理 OSSException 通常包含以下错误信息 : Code: OSS 返回给用户的错误码 Message: OSS 提供的详细错误信息 RequestId: 用于唯一标识该请求的 UUID; 当您无法解决问题时, 可以凭这个 RequestId 来请求 OSS 开发工程师的帮助 HostId: 用于标识访问的 OSS 集群, 与用户请求时使用的 Host 一致 OSS 常见错误码 错误码 描述 HTTP 状态码 AccessDenied 拒绝访问 403 BucketAlreadyExists Bucket 已经存在 409 BucketNotEmpty Bucket 不为空 409 EntityTooLarge 实体过大 400 EntityTooSmall 实体过小 400 FileGroupTooLarge 文件组过大 400 FilePartNotExist 文件 Part 不存在 400 FilePartStale 文件 Part 过时 400 InvalidArgument 参数格式错误 400 InvalidAccessKeyId AccessKeyId 不存在 403 InvalidBucketName 无效的 Bucket 名字 400 InvalidDigest 无效的摘要 400 InvalidObjectName 无效的 Object 名字 400 InvalidPart 无效的 Part 400 InvalidPartOrder 无效的 part 顺序 400 InvalidTargetBucketForLogging Logging 操作中有无效的目标 bucket 400 InternalError OSS 内部发生错误 500 MalformedXML XML 格式非法 400 MethodNotAllowed 不支持的方法

57 MissingArgument 缺少参数 411 MissingContentLength 缺少内容长度 411 NoSuchBucket Bucket 不存在 404 NoSuchKey 文件不存在 404 NoSuchUpload Multipart Upload ID 不存在 404 NotImplemented 无法处理的方法 501 PreconditionFailed 预处理错误 412 RequestTimeTooSkewed 发起请求的时间和服务器时间超出 15 分钟 403 RequestTimeout 请求超时 400 SignatureDoesNotMatch 签名错误 403 InvalidEncryptionAlgorithmError 指定的熵编码加密算法错误 400 常见问题 包冲突 如果您在使用 OSS Java SDK 时, 报如下或类似错误 : Exception in thread "main" java.lang.noclassdeffounderror: org/apache/http/ssl/truststrategy at com.aliyun.oss.ossclient.<init>(ossclient.java:268) at com.aliyun.oss.ossclient.<init>(ossclient.java:193) at com.aliyun.oss.demo.hellooss.main(hellooss.java:77) Caused by: java.lang.classnotfoundexception: org.apache.http.ssl.truststrategy at java.net.urlclassloader$1.run(urlclassloader.java:366) at java.net.urlclassloader$1.run(urlclassloader.java:355) at java.security.accesscontroller.doprivileged(native Method) at java.net.urlclassloader.findclass(urlclassloader.java:354) at java.lang.classloader.loadclass(classloader.java:425) at sun.misc.launcher$appclassloader.loadclass(launcher.java:308) at java.lang.classloader.loadclass(classloader.java:358)... 3 more 您的工程里可能有包冲突 原因是,OSS Java SDK 使用了 Apache httpclient 4.4.1, 您的工程使用了与 Apache httpclient 冲突的 Apache httpclient 或 commons-httpclient 请在您的工程目录下执行 "mvn dependency:tree", 查看工程使用的包及版本 如上述发生错误的工程里, 使用了 Apache httpclient 4.3: 56

58 包冲突有以下两种解决方法 : 使用统一版本 如果您的工程里使用与 Apache httpclient 冲突的版本, 请您也使用 版本 在 pom.xml 去掉其它版本的 Apache httpclient 依赖 如果您的工程使用了 commons-httpclient 也可能存在冲突, 请去除 commons-httpclient 解除依赖冲突 如果您的工程依赖与多个第三方包, 而第三方包又依赖不同版本的 Apache httpclient, 您的工程里会有依赖冲突, 请使用 exclusion 解除 详细请参考 maven guides OSS Java SDK 依赖以下版本的包, 冲突解决办法与 httpclient 类似, 不再赘述 缺少包 编译 / 运行 OSS Java SDK 报如下错误 : Exception in thread "main" java.lang.noclassdeffounderror: org/apache/http/auth/credentials at com.aliyun.oss.ossclient.<init>(ossclient.java:268) at com.aliyun.oss.ossclient.<init>(ossclient.java:193) at com.aliyun.oss.demo.hellooss.main(hellooss.java:76) 57

59 或 Caused by: java.lang.classnotfoundexception: org.apache.http.auth.credentials at java.net.urlclassloader$1.run(urlclassloader.java:366) at java.net.urlclassloader$1.run(urlclassloader.java:355) at java.security.accesscontroller.doprivileged(native Method) at java.net.urlclassloader.findclass(urlclassloader.java:354) at java.lang.classloader.loadclass(classloader.java:425) at sun.misc.launcher$appclassloader.loadclass(launcher.java:308) at java.lang.classloader.loadclass(classloader.java:358)... 3 more Exception in thread "main" java.lang.noclassdeffounderror: org/apache/http/protocol/httpcontext at com.aliyun.oss.ossclient.<init>(ossclient.java:268) at com.aliyun.oss.ossclient.<init>(ossclient.java:193) at com.aliyun.oss.demo.hellooss.main(hellooss.java:76) Caused by: java.lang.classnotfoundexception: org.apache.http.protocol.httpcontext at java.net.urlclassloader$1.run(urlclassloader.java:366) at java.net.urlclassloader$1.run(urlclassloader.java:355) at java.security.accesscontroller.doprivileged(native Method) at java.net.urlclassloader.findclass(urlclassloader.java:354) at java.lang.classloader.loadclass(classloader.java:425) at sun.misc.launcher$appclassloader.loadclass(launcher.java:308) at java.lang.classloader.loadclass(classloader.java:358)... 3 more 或 Exception in thread "main" java.lang.noclassdeffounderror: org/jdom/input/saxbuilder at com.aliyun.oss.internal.responseparsers.getxmlrootelement(responseparsers.java:645) at at com.aliyun.oss.ossclient.doesbucketexist(ossclient.java:471) at com.aliyun.oss.ossclient.doesbucketexist(ossclient.java:465) at com.aliyun.oss.demo.hellooss.main(hellooss.java:82) Caused by: java.lang.classnotfoundexception: org.jdom.input.saxbuilder at java.net.urlclassloader$1.run(urlclassloader.java:366) at java.net.urlclassloader$1.run(urlclassloader.java:355) at java.security.accesscontroller.doprivileged(native Method) at java.net.urlclassloader.findclass(urlclassloader.java:354) at java.lang.classloader.loadclass(classloader.java:425) at sun.misc.launcher$appclassloader.loadclass(launcher.java:308) at java.lang.classloader.loadclass(classloader.java:358) more 等类似错误, 说明您的工程缺少 OSS Java SDK 编译或运行必须的包 OSS Java SDK 依赖下列包 : aliyun-sdk-oss jar hamcrest-core-1.1.jar jdom-1.1.jar commons-codec-1.9.jar 58

60 httpclient jar commons-logging-1.2.jar httpcore jar log4j jar 其中,log4j jar 是可选的, 需要日志功能的时加入该包 其它包都是必不可少的 解决办法 : 您的工程中在加入 OSS Java SDK 依赖的包, 加入方法如下 : 如果您的工程是 Eclipse 请参考 Java-SDK 使用手册," 安装 "-> " 方式二 : 在 Eclipse 项目中导入工程依赖的包 "; 如果您的工程是 Ant 请把 OSS Java SDK 依赖的包, 放入工程 lib 目录 ; 如果您直接使用 javac/java, 请使用 -classpath/-cp 指定 OSS Java SDK 依赖的包路径, 或把 OSS Java SDK 依赖的包放入 classpath 路经下 连接超时 运行 OSS Java SDK 程序抛出如下异常 : com.aliyun.oss.clientexception: SocketException at com.aliyun.oss.common.utils.exceptionfactory.createnetworkexception(exceptionfactory.java:71) at com.aliyun.oss.common.comm.defaultserviceclient.sendrequestcore(defaultserviceclient.java:116) at com.aliyun.oss.common.comm.serviceclient.sendrequestimpl(serviceclient.java:121) at com.aliyun.oss.common.comm.serviceclient.sendrequest(serviceclient.java:67) at com.aliyun.oss.internal.ossoperation.send(ossoperation.java:92) at com.aliyun.oss.internal.ossoperation.dooperation(ossoperation.java:140) at com.aliyun.oss.internal.ossoperation.dooperation(ossoperation.java:111) at com.aliyun.oss.internal.ossbucketoperation.getbucketinfo(ossbucketoperation.java:1152) at com.aliyun.oss.ossclient.getbucketinfo(ossclient.java:1220) at com.aliyun.oss.ossclient.getbucketinfo(ossclient.java:1214) at com.aliyun.oss.demo.hellooss.main(hellooss.java:94) Caused by: org.apache.http.conn.httphostconnectexception: Connect to oss-test.oss-cn-hangzhouinternal.aliyuncs.com:80 [oss-test.oss-cn-hangzhou-internal.aliyuncs.com/ ] failed: Connection timed out: connect at org.apache.http.impl.conn.defaulthttpclientconnectionoperator.connect(defaulthttpclientconnectionop erator.java:151) at org.apache.http.impl.conn.poolinghttpclientconnectionmanager.connect(poolinghttpclientconnectionma nager.java:353) at org.apache.http.impl.execchain.mainclientexec.establishroute(mainclientexec.java:380) at org.apache.http.impl.execchain.mainclientexec.execute(mainclientexec.java:236) at org.apache.http.impl.execchain.protocolexec.execute(protocolexec.java:184) at org.apache.http.impl.execchain.redirectexec.execute(redirectexec.java:110) at org.apache.http.impl.client.internalhttpclient.doexecute(internalhttpclient.java:184) at org.apache.http.impl.client.closeablehttpclient.execute(closeablehttpclient.java:82) at com.aliyun.oss.common.comm.defaultserviceclient.sendrequestcore(defaultserviceclient.java:113)... 9 more 原因是 endpoint 错误或者网络不通, 如果不能直接找出错误 请使用 OSSProbe 工具检测 59

61 ,OSSProbe 会给出可能的错误原因 The targe server failed to respond 运行 OSS Java SDK 程序抛出如下异常 : 原因是 : 重用连接前没有检测连接是否有效, 过期的连接重用会导致上述错误 该问题是 Apache httpclient 4.4 的 bug, 详见 HTTPCLIENT-1609,4.4.1 及以后版本修复 Java SDK 前的版本使用的是 Apache httpclient 4.4, 存在上述问题 ;Java SDK 及以后的版本, 使用的是 Apache httpclient 4.4.1, 修复了该问题 如果发现该问题请升级 OSS Java SDK 到 及以后版本 其它错误 其它 OSS 返回错误的排查, 请参看常见错误及排查 Python-SDK 安装 相关资源 : github 项目 SDK API 文档 : 所有的接口, 以及类的细节 PyPi 主页 环境依赖 此版本的 Python SDK 适用于 Python 版本 首先请根据 python 官网的引导安装合适的 Python 版本 60

62 安装好 Python 后 : 在 Linux Shell 里验证 Python 版本 : $ python -V Python 上面的输出表明您已经成功安装了 Python 版本 Windows CMD 环境下验证 Python 版本 : C:\> python -V Python 上面的输出表明您已经成功安装了 Python 版本 如果提示 " 不是内部或外部命令 ", 请检查配置 " 环境变量 "-"Path", 增加 Python 的安装路径 如图 : 安装 SDK 通过 pip 安装 pip install oss2 源码安装 从 github 下载相应版本的 SDK 包, 解压后进入目录, 确认目录下有 setup.py 这个文件 : 61

SDK 手册 Java-SDK 前言 SDK 下载 - Java SDK 开发包最新版本 2.2.3:java_sdk_ zip; - github 地址 : 版本迭代详情参考这里 简介 - O

SDK 手册 Java-SDK 前言 SDK 下载 - Java SDK 开发包最新版本 2.2.3:java_sdk_ zip; - github 地址 :  版本迭代详情参考这里 简介 - O 对象存储 OSS SDK 手册 SDK 手册 Java-SDK 前言 SDK 下载 - Java SDK 开发包最新版本 2.2.3:java_sdk_20160510.zip; - github 地址 :https://github.com/aliyun/aliyun-oss-java-sdk 版本迭代详情参考这里 简介 - OSS Java SDK 适用于 JDK 6 及以上版本 ; - 本文档主要介绍

More information

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 odps-sdk 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基 开放数据处理服务 ODPS SDK SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基础功能的主体接口, 搜索关键词 "odpssdk-core" 一些

More information

新・解きながら学ぶJava

新・解きながら学ぶJava 481! 41, 74!= 40, 270 " 4 % 23, 25 %% 121 %c 425 %d 121 %o 121 %x 121 & 199 && 48 ' 81, 425 ( ) 14, 17 ( ) 128 ( ) 183 * 23 */ 3, 390 ++ 79 ++ 80 += 93 + 22 + 23 + 279 + 14 + 124 + 7, 148, 16 -- 79 --

More information

获取 Access Token access_token 是接口的全局唯一票据, 接入方调用各接口时都需使用 access_token 开发者需要进行妥善保存 access_token 的存储至少要保留 512 个字符空间 access_token 的有效期目前为 2 个小时, 需定时刷新, 重复

获取 Access Token access_token 是接口的全局唯一票据, 接入方调用各接口时都需使用 access_token 开发者需要进行妥善保存 access_token 的存储至少要保留 512 个字符空间 access_token 的有效期目前为 2 个小时, 需定时刷新, 重复 获取 Access Token access_token 是接口的全局唯一票据, 接入方调用各接口时都需使用 access_token 开发者需要进行妥善保存 access_token 的存储至少要保留 512 个字符空间 access_token 的有效期目前为 2 个小时, 需定时刷新, 重复 获取将导致上次获取的 access_token 失效 接入方可以使用 AppID 和 AppSecret

More information

云数据库 RDS SDK

云数据库 RDS SDK 云数据库 RDS SDK SDK SDK 下载 SDK 下载 最新版本 java_sdk.zip python_sdk.zip php_sdk.zip c#_sdk.zip 历史版本 2015-11-3 java_sdk.zip python_sdk.zip php_sdk.zip c#_sdk.zip JAVA 教程 JAVA 创建 Access Key 登陆阿里云账号 打开 我的 Access

More information

EJB-Programming-4-cn.doc

EJB-Programming-4-cn.doc EJB (4) : (Entity Bean Value Object ) JBuilder EJB 2.x CMP EJB Relationships JBuilder EJB Test Client EJB EJB Seminar CMP Entity Beans Session Bean J2EE Session Façade Design Pattern Session Bean Session

More information

phar 方式 使用 phar 单文件方式, 在 https://github.com/aws/aws sdk php/releases?after= 页面中, 选择 版本 , 下载已经打包好的 phar 文件, 然后在你的代码中引入这个文件即可 : require_once

phar 方式 使用 phar 单文件方式, 在 https://github.com/aws/aws sdk php/releases?after= 页面中, 选择 版本 , 下载已经打包好的 phar 文件, 然后在你的代码中引入这个文件即可 : require_once S3 PHP SDK 使用文档 S3 PHP SDK 说明 对象存储 S3 PHP SDK 使用开源的 S3 PHP SDK aws/aws sdk php 本文档介绍用户如何使用 aws/aws sdk php 来使用对象存储服务 更加详细的接口参数说明, 请在使用时参照 aws/aws sdkphp API 官方说明 http://docs.aws.amazon.com/aws sdk php/v3/api/api

More information

开放数据处理服务 ODPS 批量数据通道

开放数据处理服务 ODPS 批量数据通道 开放数据处理服务 ODPS 批量数据通道 批量数据通道 SDK 介绍 概要 ODPS Tunnel 是 ODPS 的数据通道, 用户可以通过 Tunnel 向 ODPS 中上传或者下载数据 目前 Tunnel 仅支持表 ( 不包括视图 View) 数据的上传下载 ODPS 提供的数据上传下载工具即是基于 Tunnel SDK 编写的 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk-core"

More information

SDK 手册 Java-SDK 前言 前言 SDK 下载 Java SDK 开发包 ( 版本号 2.0.7:java_sdk_ zip 版本迭代详情参考这里 简介 本文档主要介绍 OSS Java SDK 的安装和使用, 针对于 JAVA SDK 版本 2.0.7

SDK 手册 Java-SDK 前言 前言 SDK 下载 Java SDK 开发包 ( 版本号 2.0.7:java_sdk_ zip 版本迭代详情参考这里 简介 本文档主要介绍 OSS Java SDK 的安装和使用, 针对于 JAVA SDK 版本 2.0.7 对象存储 OSS SDK 手册 SDK 手册 Java-SDK 前言 前言 SDK 下载 Java SDK 开发包 (2015-11-24 版本号 2.0.7:java_sdk_20151124.zip 版本迭代详情参考这里 简介 本文档主要介绍 OSS Java SDK 的安装和使用, 针对于 JAVA SDK 版本 2.0.7 本文档假设您已经开通了阿里云 OSS 服务, 并创建了 Access

More information

chp6.ppt

chp6.ppt Java 软 件 设 计 基 础 6. 异 常 处 理 编 程 时 会 遇 到 如 下 三 种 错 误 : 语 法 错 误 (syntax error) 没 有 遵 循 语 言 的 规 则, 出 现 语 法 格 式 上 的 错 误, 可 被 编 译 器 发 现 并 易 于 纠 正 ; 逻 辑 错 误 (logic error) 即 我 们 常 说 的 bug, 意 指 编 写 的 代 码 在 执 行

More information

Chapter 9: Objects and Classes

Chapter 9: Objects and Classes Java application Java main applet Web applet Runnable Thread CPU Thread 1 Thread 2 Thread 3 CUP Thread 1 Thread 2 Thread 3 ,,. (new) Thread (runnable) start( ) CPU (running) run ( ) blocked CPU sleep(

More information

untitled

untitled 1 Outline 數 料 數 數 列 亂數 練 數 數 數 來 數 數 來 數 料 利 料 來 數 A-Z a-z _ () 不 數 0-9 數 不 數 SCHOOL School school 數 讀 school_name schoolname 易 不 C# my name 7_eleven B&Q new C# (1) public protected private params override

More information

1.JasperReport ireport JasperReport ireport JDK JDK JDK JDK ant ant...6

1.JasperReport ireport JasperReport ireport JDK JDK JDK JDK ant ant...6 www.brainysoft.net 1.JasperReport ireport...4 1.1 JasperReport...4 1.2 ireport...4 2....4 2.1 JDK...4 2.1.1 JDK...4 2.1.2 JDK...5 2.1.3 JDK...5 2.2 ant...6 2.2.1 ant...6 2.2.2 ant...6 2.3 JasperReport...7

More information

09 (File Processes) (mkdir) 9-3 (createnewfile) 9-4 (write) 9-5 (read) 9-6 (deletefile) 9-7 (deletedir) (Exercises)

09 (File Processes) (mkdir) 9-3 (createnewfile) 9-4 (write) 9-5 (read) 9-6 (deletefile) 9-7 (deletedir) (Exercises) 09 (File Processes) 9-1 9-2 (mkdir) 9-3 (createnewfile) 9-4 (write) 9-5 (read) 9-6 (deletefile) 9-7 (deletedir) (Exercises) Java Servlet 9-1 Servlet (File Processes) Client Servlet Servlet Java Java (Stream)

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc Java C++ Pascal C# C# if if if for while do while foreach while do while C# 3.1.1 ; 3-1 ischeck Test() While ischeck while static bool ischeck = true; public static void Test() while (ischeck) ; ischeck

More information

javascript sdk javascript sdk 列出 Bucket 内的对象上传 textarea 内容到 Bucket 上传本地文件生成私有下载链接生成带过期时间的私有链接删除对象下载对象拷贝对象查看文件访问权限设置文件访问权限获取静态网站配置设置静态网站删除静态网站查询对象元数据查询

javascript sdk javascript sdk 列出 Bucket 内的对象上传 textarea 内容到 Bucket 上传本地文件生成私有下载链接生成带过期时间的私有链接删除对象下载对象拷贝对象查看文件访问权限设置文件访问权限获取静态网站配置设置静态网站删除静态网站查询对象元数据查询 javascript sdk javascript sdk 列出 Bucket 内的对象上传 textarea 内容到 Bucket 上传本地文件生成私有下载链接生成带过期时间的私有链接删除对象下载对象拷贝对象查看文件访问权限设置文件访问权限获取静态网站配置设置静态网站删除静态网站查询对象元数据查询桶的多版本 Bucket 开启对象多版本支持挂起 Bucket 的多版本对象功能浏览器客户端浏览器客户端的

More information

Microsoft Word - 01.DOC

Microsoft Word - 01.DOC 第 1 章 JavaScript 简 介 JavaScript 是 NetScape 公 司 为 Navigator 浏 览 器 开 发 的, 是 写 在 HTML 文 件 中 的 一 种 脚 本 语 言, 能 实 现 网 页 内 容 的 交 互 显 示 当 用 户 在 客 户 端 显 示 该 网 页 时, 浏 览 器 就 会 执 行 JavaScript 程 序, 用 户 通 过 交 互 式 的

More information

计 算 机 系 统 应 用 http://www.c-s-a.org.cn 2016 年 第 25 卷 第 4 期 线 程 的 复 用 [2,3]. 通 常 情 况 下, 服 务 器 端 程 序 在 启 动 时 创 建 若 干 数 量 的 线 程 对 象 并 缓 存 起 来, 此 时 它 们 处 于

计 算 机 系 统 应 用 http://www.c-s-a.org.cn 2016 年 第 25 卷 第 4 期 线 程 的 复 用 [2,3]. 通 常 情 况 下, 服 务 器 端 程 序 在 启 动 时 创 建 若 干 数 量 的 线 程 对 象 并 缓 存 起 来, 此 时 它 们 处 于 1 线 程 池 技 术 在 考 试 系 统 中 的 应 用 葛 萌 1, 于 博 2, 欧 阳 宏 基 ( 咸 阳 师 范 学 院 信 息 工 程 学 院, 咸 阳 712000) ( 河 南 建 筑 职 业 技 术 学 院 信 息 工 程 系, 郑 州 450064) 1 摘 要 : 当 较 大 规 模 客 户 端 并 发 请 求 服 务 器 端 应 用 程 序 时, 传 统 的 为 每 个 请

More information

Guava学习之Resources

Guava学习之Resources Resources 提供提供操作 classpath 路径下所有资源的方法 除非另有说明, 否则类中所有方法的参数都不能为 null 虽然有些方法的参数是 URL 类型的, 但是这些方法实现通常不是以 HTTP 完成的 ; 同时这些资源也非 classpath 路径下的 下面两个函数都是根据资源的名称得到其绝对路径, 从函数里面可以看出,Resources 类中的 getresource 函数都是基于

More information

Microsoft PowerPoint - ch6 [相容模式]

Microsoft PowerPoint - ch6 [相容模式] UiBinder wzyang@asia.edu.tw UiBinder Java GWT UiBinder XML UI i18n (widget) 1 2 UiBinder HelloWidget.ui.xml: UI HelloWidgetBinder HelloWidget.java XML UI Owner class ( Composite ) UI XML UiBinder: Owner

More information

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc References (Section 5.2) Hsuan-Tien Lin Deptartment of CSIE, NTU OOP Class, March 15-16, 2010 H.-T. Lin (NTU CSIE) References OOP 03/15-16/2010 0 / 22 Fun Time (1) What happens in memory? 1 i n t i ; 2

More information

EJB-Programming-3.PDF

EJB-Programming-3.PDF :, JBuilder EJB 2.x CMP EJB Relationships JBuilder EJB Test Client EJB EJB Seminar CMP Entity Beans Value Object Design Pattern J2EE Design Patterns Value Object Value Object Factory J2EE EJB Test Client

More information

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP: ******************* * 关于 Java 测试试题 ******

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP:  ******************* * 关于 Java 测试试题 ****** ******************* * 关于 Java 测试试题 ******************* 問 1 运行下面的程序, 选出一个正确的运行结果 public class Sample { public static void main(string[] args) { int[] test = { 1, 2, 3, 4, 5 ; for(int i = 1 ; i System.out.print(test[i]);

More information

停止混流接口 请注意 : 该功能需要联系 ZEGO 技术支持开通 1 接口调用说明 http 请求方式 : POST/FORM, 需使用 https 正式环境地址 access_token=access_token (http

停止混流接口 请注意 : 该功能需要联系 ZEGO 技术支持开通 1 接口调用说明 http 请求方式 : POST/FORM, 需使用 https 正式环境地址   access_token=access_token (http 停止混流接口 请注意 : 该功能需要联系 ZEGO 技术支持开通 1 接口调用说明 http 请求方式 : POST/FORM, 需使用 https 正式环境地址 https://webapi.zego.im/cgi/stop-mix? access_token=access_token (https://webapi.zego.im/cgi/stop-mix? access_token=access_token)

More information

雲端 Cloud Computing 技術指南 運算 應用 平台與架構 10/04/15 11:55:46 INFO 10/04/15 11:55:53 INFO 10/04/15 11:55:56 INFO 10/04/15 11:56:05 INFO 10/04/15 11:56:07 INFO

雲端 Cloud Computing 技術指南 運算 應用 平台與架構 10/04/15 11:55:46 INFO 10/04/15 11:55:53 INFO 10/04/15 11:55:56 INFO 10/04/15 11:56:05 INFO 10/04/15 11:56:07 INFO CHAPTER 使用 Hadoop 打造自己的雲 8 8.3 測試 Hadoop 雲端系統 4 Nodes Hadoop Map Reduce Hadoop WordCount 4 Nodes Hadoop Map/Reduce $HADOOP_HOME /home/ hadoop/hadoop-0.20.2 wordcount echo $ mkdir wordcount $ cd wordcount

More information

(TestFailure) JUnit Framework AssertionFailedError JUnit Composite TestSuite Test TestSuite run() run() JUnit

(TestFailure) JUnit Framework AssertionFailedError JUnit Composite TestSuite Test TestSuite run() run() JUnit Tomcat Web JUnit Cactus JUnit Java Cactus JUnit 26.1 JUnit Java JUnit JUnit Java JSP Servlet JUnit Java Erich Gamma Kent Beck xunit JUnit boolean JUnit Java JUnit Java JUnit Java 26.1.1 JUnit JUnit How

More information

JavaIO.PDF

JavaIO.PDF O u t p u t S t ream j a v a. i o. O u t p u t S t r e a m w r i t e () f l u s h () c l o s e () public abstract void write(int b) throws IOException public void write(byte[] data) throws IOException

More information

Java Access 5-1 Server Client Client Server Server Client 5-2 DataInputStream Class java.io.datainptstream (extends) FilterInputStream InputStream Obj

Java Access 5-1 Server Client Client Server Server Client 5-2 DataInputStream Class java.io.datainptstream (extends) FilterInputStream InputStream Obj Message Transition 5-1 5-2 DataInputStream Class 5-3 DataOutputStream Class 5-4 PrintStream Class 5-5 (Message Transition) (Exercises) Java Access 5-1 Server Client Client Server Server Client 5-2 DataInputStream

More information

epub83-1

epub83-1 C++Builder 1 C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r 1.1 1.1.1 1-1 1. 1-1 1 2. 1-1 2 A c c e s s P a r a d o x Visual FoxPro 3. / C / S 2 C + + B u i l d e r / C

More information

Microsoft Word - template.doc

Microsoft Word - template.doc HGC efax Service User Guide I. Getting Started Page 1 II. Fax Forward Page 2 4 III. Web Viewing Page 5 7 IV. General Management Page 8 12 V. Help Desk Page 13 VI. Logout Page 13 Page 0 I. Getting Started

More information

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6:

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6: Chapter 15. Suppressed Exception CH14 Finally Block Java SE 7 try-with-resources JVM cleanup try-with-resources JVM cleanup cleanup Java SE 7 Throwable getsuppressed Throwable[] getsuppressed() Suppressed

More information

使用MapReduce读取XML文件

使用MapReduce读取XML文件 使用 MapReduce 读取 XML 文件 XML( 可扩展标记语言, 英语 :extensible Markup Language, 简称 : XML) 是一种标记语言, 也是行业标准数据交换交换格式, 它很适合在系统之间进行数据存储和交换 ( 话说 Hadoop H ive 等的配置文件就是 XML 格式的 ) 本文将介绍如何使用 MapReduce 来读取 XML 文件 但是 Had oop

More information

AL-M200 Series

AL-M200 Series NPD4754-00 TC ( ) Windows 7 1. [Start ( )] [Control Panel ()] [Network and Internet ( )] 2. [Network and Sharing Center ( )] 3. [Change adapter settings ( )] 4. 3 Windows XP 1. [Start ( )] [Control Panel

More information

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0,

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0, http://debut.cis.nctu.edu.tw/~chi Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0, : POSITIVE_INFINITY NEGATIVE_INFINITY

More information

概述

概述 OPC Version 1.6 build 0910 KOSRDK Knight OPC Server Rapid Development Toolkits Knight Workgroup, eehoo Technology 2002-9 OPC 1...4 2 API...5 2.1...5 2.2...5 2.2.1 KOS_Init...5 2.2.2 KOS_InitB...5 2.2.3

More information

untitled

untitled 4.1AOP AOP Aspect-oriented programming AOP 來說 AOP 令 理 Cross-cutting concerns Aspect Weave 理 Spring AOP 來 AOP 念 4.1.1 理 AOP AOP 見 例 來 例 錄 Logging 錄 便 來 例 行 留 錄 import java.util.logging.*; public class HelloSpeaker

More information

WebSphere Studio Application Developer IBM Portal Toolkit... 2/21 1. WebSphere Portal Portal WebSphere Application Server stopserver.bat -configfile..

WebSphere Studio Application Developer IBM Portal Toolkit... 2/21 1. WebSphere Portal Portal WebSphere Application Server stopserver.bat -configfile.. WebSphere Studio Application Developer IBM Portal Toolkit... 1/21 WebSphere Studio Application Developer IBM Portal Toolkit Portlet Doug Phillips (dougep@us.ibm.com),, IBM Developer Technical Support Center

More information

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double

More information

Kubenetes 系列列公开课 2 每周四晚 8 点档 1. Kubernetes 初探 2. 上 手 Kubernetes 3. Kubernetes 的资源调度 4. Kubernetes 的运 行行时 5. Kubernetes 的 网络管理理 6. Kubernetes 的存储管理理 7.

Kubenetes 系列列公开课 2 每周四晚 8 点档 1. Kubernetes 初探 2. 上 手 Kubernetes 3. Kubernetes 的资源调度 4. Kubernetes 的运 行行时 5. Kubernetes 的 网络管理理 6. Kubernetes 的存储管理理 7. Kubernetes 包管理理 工具 Helm 蔺礼强 Kubenetes 系列列公开课 2 每周四晚 8 点档 1. Kubernetes 初探 2. 上 手 Kubernetes 3. Kubernetes 的资源调度 4. Kubernetes 的运 行行时 5. Kubernetes 的 网络管理理 6. Kubernetes 的存储管理理 7. Kubernetes

More information

Go构建日请求千亿微服务最佳实践的副本

Go构建日请求千亿微服务最佳实践的副本 Go 构建 请求千亿级微服务实践 项超 100+ 700 万 3000 亿 Goroutine & Channel Goroutine Channel Goroutine func gen() chan int { out := make(chan int) go func(){ for i:=0; i

More information

A API Application Programming Interface 见 应 用 程 序 编 程 接 口 ARP Address Resolution Protocol 地 址 解 析 协 议 为 IP 地 址 到 对 应 的 硬 件 地 址 之 间 提 供 动 态 映 射 阿 里 云 内

A API Application Programming Interface 见 应 用 程 序 编 程 接 口 ARP Address Resolution Protocol 地 址 解 析 协 议 为 IP 地 址 到 对 应 的 硬 件 地 址 之 间 提 供 动 态 映 射 阿 里 云 内 A API Application Programming Interface 见 应 用 程 序 编 程 接 口 ARP Address Resolution Protocol 地 址 解 析 协 议 为 IP 地 址 到 对 应 的 硬 件 地 址 之 间 提 供 动 态 映 射 阿 里 云 内 容 分 发 网 络 Alibaba Cloud Content Delivery Network 一

More information

示例工程与程序 可以下载对象存储 Java SDK 的示例工程, 里面包含了很多示例程序, 可供参考 初始化 新建 Client 要使用 SDK 的功能, 需要先初始化, 代码如下所示 : ClientConfiguration opts = new ClientConfiguration(); o

示例工程与程序 可以下载对象存储 Java SDK 的示例工程, 里面包含了很多示例程序, 可供参考 初始化 新建 Client 要使用 SDK 的功能, 需要先初始化, 代码如下所示 : ClientConfiguration opts = new ClientConfiguration(); o S3 Java SDK 文档 前言 简介 对象存储 S3 接口 Java SDK 采用了开源的 aws java sdk s3 本文档主要介绍 SDK 的安装 使用与注意事项 假设您已经开通了对象存储服务, 并创建了 AccessKey 与 SecretKey 安装 在 Maven 项目中加入依赖项 向 Maven 工程中的 pom.xml 添加下述依赖项, 即可使用原生的 S3 Java SDK,

More information

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 Java V1.0.1 2007 4 10 1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 6.2.10 6.3..10 6.4 11 7.12 7.1

More information

穨control.PDF

穨control.PDF TCP congestion control yhmiu Outline Congestion control algorithms Purpose of RFC2581 Purpose of RFC2582 TCP SS-DR 1998 TCP Extensions RFC1072 1988 SACK RFC2018 1996 FACK 1996 Rate-Halving 1997 OldTahoe

More information

Chapter 9: Objects and Classes

Chapter 9: Objects and Classes Fortran Algol Pascal Modula-2 BCPL C Simula SmallTalk C++ Ada Java C# C Fortran 5.1 message A B 5.2 1 class Vehicle subclass Car object mycar public class Vehicle extends Object{ public int WheelNum

More information

IP505SM_manual_cn.doc

IP505SM_manual_cn.doc IP505SM 1 Introduction 1...4...4...4...5 LAN...5...5...6...6...7 LED...7...7 2...9...9...9 3...11...11...12...12...12...14...18 LAN...19 DHCP...20...21 4 PC...22...22 Windows...22 TCP/IP -...22 TCP/IP

More information

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii 前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii C# 7 More Effective C# C# C# C# C# C# Common Language Runtime CLR just-in-time

More information

新美大酒店开放平台SDK(.NET版)使用说明.pages

新美大酒店开放平台SDK(.NET版)使用说明.pages SDK(.NET 版 ) 使 用说明 1 SDK 包说明 1.1 获取 SDK SDK 可以在数据平台下载, 也可直接通过下载地址获得 下载地址 : http://s3.meituan.net/v1/mss_de81c933e113413ea913a772b707b9c9/open-platform-sdk/mthotelopenplatform-sdk-1.0-net.zip 下载成功后, 解压后可获得

More information

SDK 说明 Onest python SDK 来源于开源的 boto3 用户在使用 Onest 云存储服务时, 可以选择直接使用 aws 原生的 sdk, 本文档只是提供了一些常用接口的简单实示例, 如需更加详细的接口参数说明, 请在使用时参照 boto3 API 官方说明 boto3 安装 py

SDK 说明 Onest python SDK 来源于开源的 boto3 用户在使用 Onest 云存储服务时, 可以选择直接使用 aws 原生的 sdk, 本文档只是提供了一些常用接口的简单实示例, 如需更加详细的接口参数说明, 请在使用时参照 boto3 API 官方说明 boto3 安装 py Python SDK 使用文档 Python SDK 使用文档接口域名 SDK 说明安装 python SDK Client 初始化 API 接口说明 1. listbuckets 2. getbucketlocation 3. createbucket 4. headbucket 5. deletebucket 6. getbucketacl 7. putbucketacl 8. listobjects

More information

國 立 政 治 大 學 教 育 學 系 2016 新 生 入 學 手 冊 目 錄 表 11 國 立 政 治 大 學 教 育 學 系 博 士 班 資 格 考 試 抵 免 申 請 表... 46 論 文 題 目 申 報 暨 指 導 教 授... 47 表 12 國 立 政 治 大 學 碩 博 士 班 論

國 立 政 治 大 學 教 育 學 系 2016 新 生 入 學 手 冊 目 錄 表 11 國 立 政 治 大 學 教 育 學 系 博 士 班 資 格 考 試 抵 免 申 請 表... 46 論 文 題 目 申 報 暨 指 導 教 授... 47 表 12 國 立 政 治 大 學 碩 博 士 班 論 國 立 政 治 大 學 教 育 學 系 2016 新 生 入 學 手 冊 目 錄 一 教 育 學 系 簡 介... 1 ( 一 ) 成 立 時 間... 1 ( 二 ) 教 育 目 標 與 發 展 方 向... 1 ( 三 ) 授 課 師 資... 2 ( 四 ) 行 政 人 員... 3 ( 五 ) 核 心 能 力 與 課 程 規 劃... 3 ( 六 ) 空 間 環 境... 12 ( 七 )

More information

使 用 Java 语 言 模 拟 保 险 箱 容 量 门 板 厚 度 箱 体 厚 度 属 性 锁 具 类 型 开 保 险 箱 关 保 险 箱 动 作 存 取 款

使 用 Java 语 言 模 拟 保 险 箱 容 量 门 板 厚 度 箱 体 厚 度 属 性 锁 具 类 型 开 保 险 箱 关 保 险 箱 动 作 存 取 款 JAVA 程 序 设 计 ( 肆 ) 徐 东 / 数 学 系 使 用 Java 语 言 模 拟 保 险 箱 容 量 门 板 厚 度 箱 体 厚 度 属 性 锁 具 类 型 开 保 险 箱 关 保 险 箱 动 作 存 取 款 使 用 Java class 代 表 保 险 箱 public class SaveBox 类 名 类 类 体 实 现 封 装 性 使 用 class SaveBox 代 表 保

More information

C/C++ - 字符输入输出和字符确认

C/C++ - 字符输入输出和字符确认 C/C++ Table of contents 1. 2. getchar() putchar() 3. (Buffer) 4. 5. 6. 7. 8. 1 2 3 1 // pseudo code 2 read a character 3 while there is more input 4 increment character count 5 if a line has been read,

More information

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d

More information

Hadoop元数据合并异常及解决方法

Hadoop元数据合并异常及解决方法 Hadoop 元数据合并异常及解决方法 这几天观察了一下 Standby NN 上面的日志, 发现每次 Fsimage 合并完之后,Standby NN 通知 Active NN 来下载合并好的 Fsimage 的过程中会出现以下的异常信息 : 2014-04-23 14:42:54,964 ERROR org.apache.hadoop.hdfs.server.namenode.ha. StandbyCheckpointer:

More information

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

KillTest 质量更高 服务更好 学习资料   半年免费更新服务 KillTest 质量更高 服务更好 学习资料 http://www.killtest.cn 半年免费更新服务 Exam : 310-065Big5 Title : Sun Certified Programmer for the Java 2 Platform, SE 6.0 Version : Demo 1 / 14 1. 35. String #name = "Jane Doe"; 36. int

More information

3.1 num = 3 ch = 'C' 2

3.1 num = 3 ch = 'C' 2 Java 1 3.1 num = 3 ch = 'C' 2 final 3.1 final : final final double PI=3.1415926; 3 3.2 4 int 3.2 (long int) (int) (short int) (byte) short sum; // sum 5 3.2 Java int long num=32967359818l; C:\java\app3_2.java:6:

More information

財金資訊-80期.indd

財金資訊-80期.indd IPv6 / LINE YouTube TCP/IP TCP (Transmission Control Protocol) IP (Internet Protocol) (node) (address) IPv4 168.95.1.1 IPv4 1981 RFC 791 --IP IPv4 32 2 32 42 IP (Internet Service Provider ISP) IP IP IPv4

More information

4.5.1 删除单个文件 一个请求删除多个文件 4.6 列出空间里的文件 4.7 操作文件的元数据信息 5. 常见处理 5.1 简易示例 5.2 上传 InputStream 里的文件内容 5.3 遍历空间里的文件 5.5 删除某个前缀开头 ( 文件夹中 ) 的文件 欢迎使用 本文档是搜

4.5.1 删除单个文件 一个请求删除多个文件 4.6 列出空间里的文件 4.7 操作文件的元数据信息 5. 常见处理 5.1 简易示例 5.2 上传 InputStream 里的文件内容 5.3 遍历空间里的文件 5.5 删除某个前缀开头 ( 文件夹中 ) 的文件 欢迎使用 本文档是搜 搜狐云存储服务 API Reference 最后更新 2015.10.10 搜狐云存储服务 API Reference 欢迎使用 1. 基本概念 2.SCS Java 客户端 2.1 初始化客户端 2.2 设置服务访问地址 (Endpoint) 2.3 签名认证 2.3.1 签名概述 2.3.2 签名计算方法 2.3.3 使用签名的方法 2.4 获取当前用户信息 3. 空间操作 3.1 空间限制 3.1.1

More information

《大话设计模式》第一章

《大话设计模式》第一章 第 1 章 代 码 无 错 就 是 优? 简 单 工 厂 模 式 1.1 面 试 受 挫 小 菜 今 年 计 算 机 专 业 大 四 了, 学 了 不 少 软 件 开 发 方 面 的 东 西, 也 学 着 编 了 些 小 程 序, 踌 躇 满 志, 一 心 要 找 一 个 好 单 位 当 投 递 了 无 数 份 简 历 后, 终 于 收 到 了 一 个 单 位 的 面 试 通 知, 小 菜 欣 喜

More information

untitled

untitled 2006 6 Geoframe Geoframe 4.0.3 Geoframe 1.2 1 Project Manager Project Management Create a new project Create a new project ( ) OK storage setting OK (Create charisma project extension) NO OK 2 Edit project

More information

untitled

untitled How to using M-Power Report API M-Power Report API 力 了 M-Power Report -- Java (Library) M-Power Report API 行 Java M-Power Report M-Power Report API ( 30 ) PDF/HTML/CSV/XLS JPEG/PNG/SVG 料 料 OutputStream

More information

ebook140-9

ebook140-9 9 VPN VPN Novell BorderManager Windows NT PPTP V P N L A V P N V N P I n t e r n e t V P N 9.1 V P N Windows 98 Windows PPTP VPN Novell BorderManager T M I P s e c Wi n d o w s I n t e r n e t I S P I

More information

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

KillTest 质量更高 服务更好 学习资料   半年免费更新服务 KillTest 质量更高 服务更好 学习资料 http://www.killtest.cn 半年免费更新服务 Exam : 310-055Big5 Title : Sun Certified Programmer for the Java 2 Platform.SE 5.0 Version : Demo 1 / 22 1. 11. public static void parse(string str)

More information

ebook140-8

ebook140-8 8 Microsoft VPN Windows NT 4 V P N Windows 98 Client 7 Vintage Air V P N 7 Wi n d o w s NT V P N 7 VPN ( ) 7 Novell NetWare VPN 8.1 PPTP NT4 VPN Q 154091 M i c r o s o f t Windows NT RAS [ ] Windows NT4

More information

Microsoft Word - 11.doc

Microsoft Word - 11.doc 除 錯 技 巧 您 將 於 本 章 學 到 以 下 各 項 : 如 何 在 Visual C++ 2010 的 除 錯 工 具 控 制 下 執 行 程 式? 如 何 逐 步 地 執 行 程 式 的 敘 述? 如 何 監 看 或 改 變 程 式 中 的 變 數 值? 如 何 監 看 程 式 中 計 算 式 的 值? 何 謂 Call Stack? 何 謂 診 斷 器 (assertion)? 如 何

More information

while ((ch = fr.read())!= -1) { System.out.print((char) ch); fr.close(); 例 3: 用 BufferedReader 读 TXT 文件 public class FileReaderDemo3 { public static v

while ((ch = fr.read())!= -1) { System.out.print((char) ch); fr.close(); 例 3: 用 BufferedReader 读 TXT 文件 public class FileReaderDemo3 { public static v 第九章 Java I/O 流操作 实验目的 (1) 掌握文本文件的读写方法 (2) 掌握 InputStream OutputStream 的使用方法 (3) 熟悉 FileReader,BufferedReader,InputStreamReader 和 FileWriter, BufferedWriter, PrintWriter 的使用方法 ; 理解使用过滤流实现数据项的读写 :DataOutputStream,

More information

Bus Hound 5

Bus Hound 5 Bus Hound 5.0 ( 1.0) 21IC 2007 7 BusHound perisoft PC hound Bus Hound 6.0 5.0 5.0 Bus Hound, IDE SCSI USB 1394 DVD Windows9X,WindowsMe,NT4.0,2000,2003,XP XP IRP Html ZIP SCSI sense USB Bus Hound 1 Bus

More information

K7VT2_QIG_v3

K7VT2_QIG_v3 ............ 1 2 3 4 5 [R] : Enter Raid setup utility 6 Press[A]keytocreateRAID RAID Type: JBOD RAID 0 RAID 1: 2 7 RAID 0 Auto Create Manual Create: 2 RAID 0 Block Size: 16K 32K

More information

D C 93 2

D C 93 2 D9223468 3C 93 2 Java Java -- Java UML Java API UML MVC Eclipse API JavadocUML Omendo PSPPersonal Software Programming [6] 56 8 2587 56% Java 1 epaper(2005 ) Java C C (function) C (reusability) eat(chess1,

More information

Chapter #

Chapter # 第三章 TCP/IP 协议栈 本章目标 通过本章的学习, 您应该掌握以下内容 : 掌握 TCP/IP 分层模型 掌握 IP 协议原理 理解 OSI 和 TCP/IP 模型的区别和联系 TCP/IP 介绍 主机 主机 Internet TCP/IP 早期的协议族 全球范围 TCP/IP 协议栈 7 6 5 4 3 应用层表示层会话层传输层网络层 应用层 主机到主机层 Internet 层 2 1 数据链路层

More information

徐汇教育214/3月刊 重 点 关 注 高中生异性交往的小团体辅导 及效果研究 颜静红 摘 要 采用人际关系综合诊断量表 郑日昌编制并 与同性交往所不能带来的好处 带来稳定感和安全感 能 修订 对我校高一学生进行问卷测量 实验组前后测 在 够度过更快乐的时光 获得与别人友好相处的经验 宽容 量表总分和第 4 项因子分 异性交往困扰 上均有显著差 大度和理解力得到发展 得到掌握社会技术的机会 得到 异

More information

RunPC2_.doc

RunPC2_.doc PowerBuilder 8 (5) PowerBuilder Client/Server Jaguar Server Jaguar Server Connection Cache Thin Client Internet Connection Pooling EAServer Connection Cache Connection Cache Connection Cache Connection

More information

附录J:Eclipse教程

附录J:Eclipse教程 附 录 J:Eclipse 教 程 By Y.Daniel Liang 该 帮 助 文 档 包 括 以 下 内 容 : Eclipse 入 门 选 择 透 视 图 创 建 项 目 创 建 Java 程 序 编 译 和 运 行 Java 程 序 从 命 令 行 运 行 Java Application 在 Eclipse 中 调 试 提 示 : 在 学 习 完 第 一 章 后 使 用 本 教 程 第

More information

untitled

untitled JavaEE+Android - 6 1.5-2 JavaEE web MIS OA ERP BOSS Android Android Google Map office HTML CSS,java Android + SQL Sever JavaWeb JavaScript/AJAX jquery Java Oracle SSH SSH EJB+JBOSS Android + 1. 2. IDE

More information

全国计算机技术与软件专业技术资格(水平)考试

全国计算机技术与软件专业技术资格(水平)考试 全 国 计 算 机 技 术 与 软 件 专 业 技 术 资 格 ( 水 平 ) 考 试 2008 年 上 半 年 程 序 员 下 午 试 卷 ( 考 试 时 间 14:00~16:30 共 150 分 钟 ) 试 题 一 ( 共 15 分 ) 阅 读 以 下 说 明 和 流 程 图, 填 补 流 程 图 中 的 空 缺 (1)~(9), 将 解 答 填 入 答 题 纸 的 对 应 栏 内 [ 说 明

More information

1. 访 问 最 新 发 行 公 告 信 息 jconnect for JDBC 7.0 1. 访 问 最 新 发 行 公 告 信 息 最 新 版 本 的 发 行 公 告 可 以 从 网 上 获 得 若 要 查 找 在 本 产 品 发 布 后 增 加 的 重 要 产 品 或 文 档 信 息, 请 访

1. 访 问 最 新 发 行 公 告 信 息 jconnect for JDBC 7.0 1. 访 问 最 新 发 行 公 告 信 息 最 新 版 本 的 发 行 公 告 可 以 从 网 上 获 得 若 要 查 找 在 本 产 品 发 布 后 增 加 的 重 要 产 品 或 文 档 信 息, 请 访 发 行 公 告 jconnect for JDBC 7.0 文 档 ID:DC74874-01-0700-01 最 后 修 订 日 期 :2010 年 3 月 2 日 主 题 页 码 1. 访 问 最 新 发 行 公 告 信 息 2 2. 产 品 摘 要 2 3. 特 殊 安 装 说 明 2 3.1 查 看 您 的 jconnect 版 本 3 4. 特 殊 升 级 指 导 3 4.1 迁 移 3

More information

59 1 CSpace 2 CSpace CSpace URL CSpace 1 CSpace URL 2 Lucene 3 ID 4 ID Web 1. 2 CSpace LireSolr 3 LireSolr 3 Web LireSolr ID

59 1 CSpace 2 CSpace CSpace URL CSpace 1 CSpace URL 2 Lucene 3 ID 4 ID Web 1. 2 CSpace LireSolr 3 LireSolr 3 Web LireSolr ID 58 2016. 14 * LireSolr LireSolr CEDD Ajax CSpace LireSolr CEDD Abstract In order to offer better image support services it is necessary to extend the image retrieval function of our institutional repository.

More information

(Guangzhou) AIT Co, Ltd V 110V [ ]! 2

(Guangzhou) AIT Co, Ltd V 110V [ ]! 2 (Guangzhou) AIT Co, Ltd 020-84106666 020-84106688 http://wwwlenxcn Xi III Zebra XI III 1 (Guangzhou) AIT Co, Ltd 020-84106666 020-84106688 http://wwwlenxcn 230V 110V [ ]! 2 (Guangzhou) AIT Co, Ltd 020-84106666

More information

TX-NR3030_BAS_Cs_ indd

TX-NR3030_BAS_Cs_ indd TX-NR3030 http://www.onkyo.com/manual/txnr3030/adv/cs.html Cs 1 2 3 Speaker Cable 2 HDMI OUT HDMI IN HDMI OUT HDMI OUT HDMI OUT HDMI OUT 1 DIGITAL OPTICAL OUT AUDIO OUT TV 3 1 5 4 6 1 2 3 3 2 2 4 3 2 5

More information

Socket Socket TcpClient Socket.Connect TcpClient.Connect Socket.Send / Receive NetworkStream 6-5

Socket Socket TcpClient Socket.Connect TcpClient.Connect Socket.Send / Receive NetworkStream 6-5 6 6-1 6-2 Socket 6-2-1 Socket 6-2-2 TcpClient 6-3 6-3-1 Socket.Connect 6-3-2 TcpClient.Connect 6-4 6-4-1 Socket.Send / Receive 6-4-2 NetworkStream 6-5 6-5-1 Socket.Close 6-5-2 TcpClient.Close 6-6 DateTime

More information

<4D6963726F736F667420506F776572506F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074>

<4D6963726F736F667420506F776572506F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074> 程 序 设 计 实 习 INFO130048 3-2.C++ 面 向 对 象 程 序 设 计 重 载 继 承 多 态 和 聚 合 复 旦 大 学 计 算 机 科 学 与 工 程 系 彭 鑫 pengxin@fudan.edu.cn 内 容 摘 要 方 法 重 载 类 的 继 承 对 象 引 用 和 拷 贝 构 造 函 数 虚 函 数 和 多 态 性 类 的 聚 集 复 旦 大 学 计 算 机 科 学

More information

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1 21 , 7, Windows,,,, : 010-62782989 13501256678 13801310933,,,, ;,, ( CIP) /,,. : ;, 2005. 11 ( 21 ) ISBN 7-81082 - 634-4... - : -. TP316-44 CIP ( 2005) 123583 : : : : 100084 : 010-62776969 : 100044 : 010-51686414

More information

Important Notice SUNPLUS TECHNOLOGY CO. reserves the right to change this documentation without prior notice. Information provided by SUNPLUS TECHNOLO

Important Notice SUNPLUS TECHNOLOGY CO. reserves the right to change this documentation without prior notice. Information provided by SUNPLUS TECHNOLO Car DVD New GUI IR Flow User Manual V0.1 Jan 25, 2008 19, Innovation First Road Science Park Hsin-Chu Taiwan 300 R.O.C. Tel: 886-3-578-6005 Fax: 886-3-578-4418 Web: www.sunplus.com Important Notice SUNPLUS

More information

速递易开放平台认证规范

速递易开放平台认证规范 姜润 曾浩 Table of Contents 1. 规范... 1 2. 示例... 2 3. 相关错误说明... 2 4. 语言示例... 3 4.1. Java... 3 4.2. C#... 4 4.3. python... 6 4.4. php... 7 1.# 规范 速递易开放平台 API 采用标准的

More information

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 -> 目录 1 大概思路... 1 2 创建 WebAPI... 1 3 创建 CrossMainController 并编写... 1 4 Nuget 安装 microsoft.aspnet.webapi.cors... 4 5 跨域设置路由... 4 6 编写 Jquery EasyUI 界面... 5 7 运行效果... 7 8 总结... 7 1 1 大概思路 创建 WebAPI 创建 CrossMainController

More information

ebook39-6

ebook39-6 6 first-in-first-out, FIFO L i n e a r L i s t 3-1 C h a i n 3-8 5. 5. 3 F I F O L I F O 5. 5. 6 5. 5. 6.1 [ ] q u e n e ( r e a r ) ( f r o n t 6-1a A 6-1b 6-1b D C D 6-1c a) b) c) 6-1 F I F O L I F ADT

More information

1.ai

1.ai HDMI camera ARTRAY CO,. LTD Introduction Thank you for purchasing the ARTCAM HDMI camera series. This manual shows the direction how to use the viewer software. Please refer other instructions or contact

More information

无类继承.key

无类继承.key 无类继承 JavaScript 面向对象的根基 周爱 民 / aimingoo aiming@gmail.com https://aimingoo.github.io https://github.com/aimingoo rand = new Person("Rand McKinnon",... https://docs.oracle.com/cd/e19957-01/816-6408-10/object.htm#1193255

More information

C H A P T E R 7 Windows Vista Windows Vista Windows Vista FAT16 FAT32 NTFS NTFS New Technology File System NTFS

C H A P T E R 7 Windows Vista Windows Vista Windows Vista FAT16 FAT32 NTFS NTFS New Technology File System NTFS C H P T E R 7 Windows Vista Windows Vista Windows VistaFT16 FT32NTFS NTFSNew Technology File System NTFS 247 6 7-1 Windows VistaTransactional NTFS TxFTxF Windows Vista MicrosoftTxF CIDatomicity - Consistency

More information

C/C++ - 文件IO

C/C++ - 文件IO C/C++ IO Table of contents 1. 2. 3. 4. 1 C ASCII ASCII ASCII 2 10000 00100111 00010000 31H, 30H, 30H, 30H, 30H 1, 0, 0, 0, 0 ASCII 3 4 5 UNIX ANSI C 5 FILE FILE 6 stdio.h typedef struct { int level ;

More information

本章学习目标 小风 Java 实战系列教程 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc

本章学习目标 小风 Java 实战系列教程 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc 本章学习目标 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 配置视图解析器 @RequestMapping 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc 和 Struts2 都属于表现层的框架, 它是 Spring 框架的一部分, 我们可 以从 Spring 的整体结构中看得出来 :

More information

Windows RTEMS 1 Danilliu MMI TCP/IP QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos eco

Windows RTEMS 1 Danilliu MMI TCP/IP QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos eco Windows RTEMS 1 Danilliu MMI TCP/IP 80486 QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos ecos Email www.rtems.com RTEMS ecos RTEMS RTEMS Windows

More information

2009年3月全国计算机等级考试二级Java语言程序设计笔试试题

2009年3月全国计算机等级考试二级Java语言程序设计笔试试题 2009 年 3 月 全 国 计 算 机 等 级 考 试 笔 试 试 卷 二 级 Java 语 言 程 序 设 计 ( 考 试 时 间 90 分 钟, 满 分 100 分 ) 一 选 择 题 ( 每 题 2 分, 共 70 分 ) 下 列 各 题 A) B) C) D) 四 个 选 项 中, 只 有 一 个 选 项 是 正 确 的 请 将 正 确 选 项 填 涂 在 答 题 卡 相 应 位 置 上,

More information

untitled

untitled 1 行 行 行 行.NET 行 行 類 來 行 行 Thread 類 行 System.Threading 來 類 Thread 類 (1) public Thread(ThreadStart start ); Name 行 IsAlive 行 行狀 Start 行 行 Suspend 行 Resume 行 行 Thread 類 (2) Sleep 行 CurrentThread 行 ThreadStart

More information

未命名

未命名 1 Synchronized synchronized Java ( ) Synchronized Java unlock lock load assign unlock (happen-before) lock Synchronized null " " HotSpot JVM Object Monitor synchronized 1 2 Class synchronized monitor Class

More information

Serial ATA ( Silicon Image SiI3114)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 5 (4) S A T A... 8 (5) S A T A... 10

Serial ATA ( Silicon Image SiI3114)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 5 (4) S A T A... 8 (5) S A T A... 10 Serial ATA ( Silicon Image SiI3114)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 5 (4) S A T A... 8 (5) S A T A... 10 Ác Åé å Serial ATA ( Silicon Image SiI3114) S A T A (1) SATA (2)

More information

WWW PHP

WWW PHP WWW PHP 2003 1 2 function function_name (parameter 1, parameter 2, parameter n ) statement list function_name sin, Sin, SIN parameter 1, parameter 2, parameter n 0 1 1 PHP HTML 3 function strcat ($left,

More information

PowerPoint 演示文稿

PowerPoint 演示文稿 The BitCoin Scripting Language 交易实例 交易结构 "result": { "txid": "921a dd24", "hash": "921a dd24", "version": 1, "size": 226, "locktime": 0, "vin": [ ], "vout": [ ], "blockhash": "0000000000000000002c510d

More information