本文介绍了如何使用 Java 客户端库发送 Google Data API(“GData”)查询以及解读返回的响应。
Google 提供了一组使用各种编程语言的客户端库,用于与具有数据 API 的服务进行交互。使用这些库,您可以构建 GData 请求,将其发送到服务并接收响应。
本文档提供了一些有关使用 Java 客户端库的常规信息,以及一组常见用途示例。
如需使用此客户端库,您必须运行 Java 1.5。
本指南中的示例引用的是 Google Calendar API,但本指南的内容并不是有关使用 Calendar API 的准确或最新的指南。如需了解如何将 Java 客户端库与特定服务的数据 API 配合使用,请参阅服务专属文档。例如,如果您使用的是 Google 日历,请参阅 Calendar Data API 开发者指南。
目录
观众
本文档适用于想要编写可与 GData 服务进行交互的客户端应用的 Java 程序员。
本文假定您了解 Google Data API 协议的一般概念。本文档还假定您知道如何使用 Java 编程。
有关客户端库提供的类和方法的参考信息,请参阅 Java 客户端库 API 参考文档(采用 Javadoc 格式)。
本文档是按顺序阅读的,其中每个示例都基于早期的示例。
数据模型概览
Java 客户端库使用一组类来表示 Google Data API 所使用的元素。例如,有一个 Feed 类,它对应于 <atom:feed>
元素;它有用于创建条目、获取和设置各种子元素值等的方法。此外,还有一个与 <atom:entry>
元素对应的 Entry 类。并非 Google Data API 中定义的每个元素都有自己的类;如需了解详情,请参阅参考文档。
该库可自动解析 Atom 内容,并将 Atom 元素的值放入相应的对象中。例如,getFeed
方法会获取 Feed,对其进行解析,并返回包含所生成值的 Feed 对象。
要向服务发送 Feed 或条目,请创建 Feed 或条目对象,然后调用库方法(例如 insert
方法),自动将对象转换为 XML 并发送。
如果您愿意,可以自行解析和/或生成 XML;最简单的方法是使用相应的第三方库(如 Rome)实现此目的。
就像 Google Data API 的 XML 语法一样可扩展,对应的对象模型也是可扩展的。例如,客户端库提供与 Google 数据命名空间中定义的元素相对应的类。
教程和示例
以下示例展示了如何使用 Java 客户端库发送各种数据 API 请求。
为了让用户更有针对性,这些示例展示了如何与 Google 日历的特定服务交互。我们会指出 Google 日历与其他 Google 服务的不同之处,以帮助您调整这些示例,以便在其他服务中使用。要详细了解 Google 日历,请参阅 Google Calendar Data API 文档。
构建并运行客户端
如需编译本文档中的示例,您需要使用以下 import 语句:
import com.google.gdata.client.*; import com.google.gdata.client.calendar.*; import com.google.gdata.data.*; import com.google.gdata.data.extensions.*; import com.google.gdata.util.*; import java.net.URL;
请求 Feed
如 Google Calendar Data API 文档中所述,您可以通过将以下 HTTP 请求发送到日历来请求日历 Feed:
GET http://www.google.com/calendar/feeds/userID/private/full
当然,您必须将 userID
替换为用户的电子邮件地址;如需了解详情,请参阅 Google 日历文档。您可以改用特殊的默认网址与日历互动(如日历文档中所述),但在此文档中,我们将使用包含用户 ID 的完整私人 Feed 网址。
您还必须提供适当的身份验证。该示例与日历文档中的第一个示例的主要区别在于:(1) 此示例包含身份验证,并且 (2) 此示例使用更通用的 GoogleService 类,而不是特定于日历的 CalendarService 类。
请注意,我们在此处使用的身份验证系统(称为“安装式 Google 身份验证”)仅适用于安装式客户端应用(如桌面客户端),不适用于 Web 应用。如需详细了解身份验证,请参阅 Google 帐号身份验证文档。
要使用 Java 客户端库请求日历 Feed,对于电子邮件地址为“liz@gmail.com”且密码为“mypassword”的用户,请使用以下代码:
// Set up the URL and the object that will handle the connection: URL feedUrl = new URL("http://www.google.com/calendar/feeds/liz@gmail.com/private/full"); GoogleService myService = new GoogleService("cl", "exampleCo-exampleApp-1"); myService.setUserCredentials("liz@gmail.com", "mypassword"); // Mark the feed as an Event feed: new EventFeed().declareExtensions(myService.getExtensionProfile()); // Send the request and receive the response: Feed myFeed = myService.getFeed(feedUrl, Feed.class);
GoogleService
类表示与 GData 服务的客户端连接(通过身份验证)。使用客户端库向服务发送查询的一般过程包括以下步骤:
- 获取或构造适当的网址。
- 如果要向服务发送数据(例如,如果您要插入新的条目),则使用客户端库类将原始数据转换为对象。(如果您在此示例中请求了 Feed,则此步骤不适用。)
- 创建一个新的
GoogleService
实例,设置服务名称(例如日历的"cl"
)和应用的名称(格式为companyName-applicationName-versionID
)。 - 设置适当的凭据。
- 向客户端库指明 Feed 将使用哪些扩展程序,以便库可以正确解析返回的 Feed。
- 调用方法以发送请求并接收任何结果。
setUserCredentials
方法指定客户端代表其发送查询的用户的 ID 和密码。本文档中的示例使用“适用于已安装应用的身份验证”身份验证系统;有关身份验证系统的详细信息,请参阅 Google 帐号身份验证文档。
设置凭据后,您可以调用 declareExtensions
方法来指明 Feed 将使用哪些附加信息。在本例中,我们假设该 Feed 是事件 Feed,因此将使用由事件种类定义的附加信息。
如需请求整个 Feed,可调用 getFeed
方法,该方法会接受一个网址并返回在该网址上找到的整个 Feed。我们将在本文档的后面部分介绍如何发送更具体的查询。
与 GoogleService
类的其他方法一样,getFeed
会根据需要处理身份验证和重定向。
插入新项
如需创建新的日历活动,您可以使用以下代码:
URL postUrl = new URL("http://www.google.com/calendar/feeds/liz@gmail.com/private/full"); EventEntry myEntry = new EventEntry(); myEntry.setTitle(new PlainTextConstruct("Tennis with Darcy")); myEntry.setContent(new PlainTextConstruct("Meet for a quick lesson.")); Person author = new Person("Elizabeth Bennet", null, "liz@gmail.com"); myEntry.getAuthors().add(author); DateTime startTime = DateTime.parseDateTime("2006-04-17T15:00:00-08:00"); DateTime endTime = DateTime.parseDateTime("2006-04-17T17:00:00-08:00"); When eventTimes = new When(); eventTimes.setStartTime(startTime); eventTimes.setEndTime(endTime); myEntry.addTime(eventTimes); // Send the request and receive the response: EventEntry insertedEntry = myService.insert(postUrl, myEntry);
设置网址后,我们会构建一个 EventEntry
对象;EventEntry
派生自抽象基类 BaseEntry
,后者是 Entry
类的父类(代表 <atom:entry>
元素的父类)。
EventEntry
类表示事件种类;如需了解详情,请参阅种类文档。对于非 Google 日历服务,您可以将返回的条目分配给 Entry
对象,而不是 EventEntry
对象。
条目标题是一个 TextConstruct
,这是一个包含各种格式(纯文本、HTML 或 XHTML)的文本的类。条目内容由 Content
对象表示,该类可容纳纯文本或其他形式的内容,包括 XML 和二进制数据。(但 setContent
方法也可以接受 TextConstruct
。)
每个作者都以姓名、URI 和电子邮件地址表示。(在此示例中,我们省略了 URI)。您可以通过调用条目的 getAuthors().add
方法为条目添加作者。
我们使用的是之前示例中创建的 GoogleService
对象。在本例中,调用的方法是 insert
,这会将一个项发送到指定的插入网址。
该服务会返回新创建的条目,其中可能包含服务器生成的其他元素,如该条目的修改网址。
HTTP 状态代码会作为异常返回。
上面的代码等同于发送 POST http://www.google.com/calendar/feeds/liz@gmail.com/private/full
(以适当的身份验证方式)并以事件种类的形式提供条目。
请求特定条目
通过以下代码,您可以请求在上一个示例中插入的特定条目。
在本系列示例中,由于条目已返回所插入的条目,因此不必检索该条目;但只要您知道条目的 URI,就可以使用相同的方法。
URL entryUrl = new URL(insertedEntry.getSelfLink().getHref()); EventEntry retrievedEntry = myService.getEntry(entryUrl, EventEntry.class);
插入的条目具有 getSelfLink
方法,该方法会返回一个包含该条目网址的 Link
对象。Link
类具有 getHref
方法,用于以 String
的形式返回网址,我们可以据此创建网址对象。
然后,我们只需调用服务的 getEntry
方法来获取条目。
请注意,我们将 EventEntry.class
作为参数提供给 getEntry
,以表明我们期望服务返回事件,而不是仅返回普通条目。对于 Google 日历之外的其他服务,您可能需要改为传递 Entry.class
。
以上代码等同于将 GET http://www.google.com/calendar/feeds/liz@gmail.com/private/full/entryID
发送到具有适当身份验证的日历。
搜索条目
如需从全文搜索中检索第一个匹配项,请使用以下代码:
Query myQuery = new Query(feedUrl); myQuery.setFullTextQuery("Tennis"); Feed myResultsFeed = myService.query(myQuery, Feed.class); if (myResultsFeed.getEntries().size() > 0) { Entry firstMatchEntry = myResultsFeed.getEntries().get(0); String myEntryTitle = firstMatchEntry.getTitle().getPlainText(); }
此示例首先构造了一个 Query
对象,该对象主要由网址以及关联的查询参数组成。每个标准 GData 查询参数都有一个 setter 方法。您还可以使用 addCustomParameter
方法为特定服务设置自定义查询参数。
构建 Query
后,我们会将其传递给服务的 query
方法,该方法会返回包含查询结果的 Feed。另一种方法是自行构造网址(通过将查询参数附加到 Feed 网址),然后调用 getFeed
方法,但 query
方法可提供实用的抽象层,因此您无需自行构建网址。
Feed 的 getEntries
方法会返回 Feed 中的条目列表;getEntries().size
会返回 Feed 中的条目数。
在本例中,如果查询返回任何结果,我们会将第一个匹配结果分配给 Entry
对象。然后,我们使用 Entry
类的 getTitle().getPlainText
方法检索该条目的标题并将其转换为文本。
上面的代码相当于将 GET http://www.google.com/calendar/feeds/liz@gmail.com/private/full?q=Tennis
发送到日历。
按类别查询
注意:Google 日历不会将标签与活动关联,因此此示例不适用于 Google 日历。
要检索的 Feed 包括与之前的全文搜索相匹配的所有条目、属于特定类别或具有特定标签的条目,请使用以下代码:
Category myCategory = new Category("by_liz"); CategoryFilter myCategoryFilter = new CategoryFilter(myCategory); myQuery.addCategoryFilter(myCategoryFilter); Feed myCategoryResultsFeed = myService.query(myQuery, Feed.class);
当然,Category
类表示要在类别过滤器中使用的类别。Query.CategoryFilter
类可以包含多个类别,但在本例中,我们构造的过滤器只有一个类别。
然后,我们将该过滤器添加到现有查询,该查询仍然包含上一个示例中的全文查询字符串。
我们再次使用 query
方法将查询发送到服务。
如果 Google 日历允许类别搜索,上述代码等同于向 Google 日历发送 GET http://www.google.com/calendar/feeds/liz@gmail.com/private/full/-/by_liz?q=Tennis
。
更新商品
如需更新现有项,请使用以下代码。在此示例中,我们将之前检索到的条目的标题从“原来的网球比赛”和“重要会议”更改为“重要会议”。
retrievedEntry.setTitle(new PlainTextConstruct("Important meeting")); URL editUrl = new URL(retrievedEntry.getEditLink().getHref()); EventEntry updatedEntry = myService.update(editUrl, myEntry);
首先,我们为之前提取的条目设置新标题。然后,我们使用 getEditLink
方法获取该条目的修改网址。然后,我们调用服务的 update
方法以发送更新后的条目。
该服务会返回更新后的条目,包括该条目新版本的新网址。(如需详细了解条目版本,请参阅协议参考文档的乐观并发部分。)
上面的代码大致等同于向服务发送 PUT http://www.google.com/calendar/feeds/liz@gmail.com/private/full/entryID
,以及新条目(Atom 格式)来替换原始条目。
删除商品
如需删除更新后的条目,请使用以下代码:
URL deleteUrl = new URL(updatedEntry.getEditLink().getHref()); myService.delete(deleteUrl);
要删除的网址与修改网址相同,因此此示例与上一个示例非常相似,只不过我们调用的是 delete
方法,而不是 update
。
上面的代码大致相当于将 DELETE http://www.google.com/calendar/feeds/liz@gmail.com/private/full/entryID
发送到服务。
参考
有关客户端库提供的类和方法的参考信息,请参阅 Java 客户端库 API 参考文档(采用 Javadoc 格式)。