本文档介绍了如何使用 Java 客户端库发送 Google Data API (“GData”) 查询并解读返回的响应。
Google 提供了一组客户端库,支持多种编程语言,可用于与具有 Data API 的服务进行交互。使用这些库,您可以构建 GData 请求、将其发送到服务并接收响应。
本文档提供了一些有关使用 Java 客户端库的常规信息,以及一组常见用途示例。
如需使用此客户端库,您必须运行 Java 1.5。
本指南的示例中提到了 Google Calendar API,但本指南并非使用 Calendar API 的准确或最新指南。如需了解如何将 Java 客户端库与特定服务的数据 API 搭配使用,请参阅特定于服务的文档。例如,如果您使用的是日历,请参阅 Calendar Data API 开发者指南。
目录
受众群体
本文档面向希望编写可与 GData 服务互动的客户端应用的 Java 程序员。
本文档假定您了解 Google Data API 协议背后的总体思路。本文档还假定您了解如何使用 Java 编程。
如需了解客户端库提供的类和方法的参考信息,请参阅 Java 客户端库 API 参考文档(采用 Javadoc 格式)。
建议您按顺序阅读本文档;每个示例都是基于之前的示例构建的。
数据模型概览
Java 客户端库使用一组类来表示 Google Data API 使用的元素。例如,有一个 Feed 类,它对应于 <atom:feed>
元素;它具有用于创建条目、获取和设置各种子元素的值等方法。还有一个 Entry 类,对应于 <atom:entry>
元素。并非 Google Data API 中定义的每个元素都有自己的类;如需了解详情,请参阅参考文档。
该库可以自动解析 Atom 内容,并将 Atom 元素的值放入相应的对象中。例如,getFeed
方法会获取 Feed,对其进行解析,然后返回一个包含结果值的 Feed 对象。
如需向服务发送 Feed 或条目,您可以创建一个 Feed 或 Entry 对象,然后调用库方法(例如 insert
方法)自动将该对象转换为 XML 并发送。
如果您愿意,可以自行解析和/或生成 XML;最简单的方法是使用合适的第三方库,例如 Rome。
与 Google Data API 的 XML 语法一样,相应的对象模型也是可扩展的。例如,客户端库提供了与 Google Data 命名空间中定义的元素对应的类。
教程和示例
以下示例展示了如何使用 Java 客户端库发送各种 Data API 请求。
为了使这些示例更具体,我们展示了如何与特定服务(即 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 文档中所述,您可以向 Google 日历发送以下 HTTP 请求来请求日历 Feed:
GET http://www.google.com/calendar/feeds/userID/private/full
当然,您必须将 userID
替换为用户的电子邮件地址;有关详情,请参阅日历文档。您也可以使用用于与日历互动的特殊默认网址(如日历文档中所述),但本文档将使用包含用户 ID 的不公开完整 Feed 网址。
您还必须提供适当的身份验证信息。此示例与日历文档中的第一个示例的主要区别在于:(1) 此示例包含身份验证;(2) 此示例使用更通用的 GoogleService 类,而不是特定于日历的 CalendarService 类。
请注意,我们在此处使用的身份验证系统(称为“适用于已安装应用的 Google 身份验证”)仅适用于已安装的客户端应用(例如桌面客户端),不适用于 Web 应用。如需详细了解身份验证,请参阅 Google 账号身份验证文档。
如需使用 Java 客户端库为电子邮件地址为“liz@gmail.com”且密码为“mypassword”的用户请求日历 Feed,请使用以下代码:
// 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 是一个 Event Feed,因此它将使用 Event kind 定义的扩展。
如需请求整个 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
类的父类,而 Entry
类表示 <atom:entry>
元素。
EventEntry
类表示一种事件类型;如需了解详情,请参阅“类型”文档。对于日历以外的服务,您可能会将返回的条目分配给 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
(具有适当的身份验证),并以 Event 类型的形式提供条目。
请求特定条目
通过以下代码,您可以请求在上一个示例中插入的特定条目。
在本系列示例中,检索该条目并不是必需的,因为日历已返回插入的条目;但只要您知道条目的 URI,就可以应用相同的技术。
URL entryUrl = new URL(insertedEntry.getSelfLink().getHref()); EventEntry retrievedEntry = myService.getEntry(entryUrl, EventEntry.class);
插入的条目具有一个方法 getSelfLink
,该方法会返回一个包含条目网址的 Link
对象。Link
类有一个 getHref
方法,该方法会以 String
的形式返回网址,我们可以从中创建网址对象。
然后,我们只需调用服务的 getEntry
方法即可获取条目。
请注意,我们将 EventEntry.class
作为参数传递给 getEntry
,这表示我们特别希望服务返回 Event,而不仅仅是纯条目。对于日历以外的服务,您可能只需传递 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
方法将查询发送到服务。
如果日历允许类别搜索,则上述代码相当于向日历发送 GET http://www.google.com/calendar/feeds/liz@gmail.com/private/full/-/by_liz?q=Tennis
。
更新商品
如需更新现有商品,请使用以下代码。在此示例中,我们将之前检索到的条目的标题从旧文本(“与 Darcy 一起打网球”)更改为“重要会议”。
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 格式)。