Java 语言指南

重要提示:本文档是在 2012 年之前撰写的。身份验证选项 OAuth 1.0、AuthSub 和 ClientLogin) 已正式弃用 自 2012 年 4 月 20 日起不再提供。我们建议您迁移到 OAuth 2.0

通过 Google 协作平台数据 API,客户端应用可以访问、发布和修改 Google 协作平台中的内容。 您的客户端应用还可以请求获取近期活动列表、提取修订历史记录以及下载附件。

除了提供有关协作平台数据 API 功能的一些背景信息之外,本指南还提供了与该 API 交互的示例。 使用 Java 客户端库。有关设置客户端库的帮助,请参阅 开始使用 Google 数据 Java 客户端库。如果您对 详细了解 Java 客户端库用来与传统版 Google 协作平台 API 交互的基本协议,请参阅 协议指南

受众群体

本文档适用于想要编写与 Google 协作平台交互的客户端应用程序的开发者 使用 Google Data Java 客户端库

使用入门

Google 协作平台使用 Google 账号或 G Suite 账号进行身份验证。如果您已有账号,那就万事俱备了。 您也可以创建新账号

安装库

如需有关设置和安装客户端库的帮助,请参阅 Google Data Java 客户端库使用入门。如果您使用的是 Eclipse,本文也介绍了 如何使用 Google Data API Eclipse 插件设置项目。在开始之前,您需要拥有以下几样东西:

  1. 安装 Java 1.5 或更高版本
  2. 下载客户端库(最新版 gdata-src.java.zip
  3. 下载依赖项列表
  4. 下载示例应用(最新版 gdata-samples.java.zip

安装 .jar 文件后,您需要将以下内容添加到项目中:

  1. java/lib/gdata-sites-2.0.jar - 此处的 2.0 版适用于传统版 Google 协作平台 API 1.4 版。
  2. java/lib/gdata-core-1.0.jar
  3. java/lib/gdata-client-1.0.jar
  4. java/lib/gdata-spreadsheet-3.0.jar(如果使用列表页面 / 列表项)

此外,请务必添加依赖项 JAR(gdata-media-1.0.jarmail.jargoogle-collect....jar)。

运行示例应用

完整的有效示例应用位于 gdata-samples.java.zip 下载内容的 /java/sample/sites 子目录中。 也可通过 /trunk/java/sample/sites/ 获取源代码 通过“Source”标签页访问 SVN 代码库中。借助 SitesDemo.java,用户可执行多种操作,演示如何使用传统版 协作平台 API。

请注意,您需要添加 java/sample/util/lib/sample-util.jar 才能运行示例。

开始您自己的项目

提示:有关使用我们的 Eclipse 插件进行快速设置的信息,请参阅将 Eclipse 与 Google Data API 结合使用一文。

根据应用的需求,您需要执行多次导入操作。我们建议从以下导入开始:

import com.google.gdata.client.*;
import com.google.gdata.client.sites.*;
import com.google.gdata.data.*;
import com.google.gdata.data.acl.*;
import com.google.gdata.data.media.*;
import com.google.gdata.data.sites.*;
import com.google.gdata.data.spreadsheet.*;  // If working with listpages / listitems
import com.google.gdata.util.*;

接下来,您还需要设置 SitesService 对象,以表示客户端与传统版 Google 协作平台 API 的连接:

SitesService client = new SitesService("yourCo-yourAppName-v1");

applicationName 参数应遵循以下格式:company-applicationname-version。此参数用于记录目的。

注意:本指南的其余部分假定您在变量 client 中创建了一个 SitesService

向传统版 Google 协作平台 API 进行身份验证

Java 客户端库可用于处理公共供稿或私有供稿。通过 Google 协作平台数据 API,您可以访问私有和公开 Feed,具体取决于网站权限和您尝试执行的操作。例如,您可以读取 一个公开站点,但不对其进行更新 - 这需要通过身份验证的客户端。为此,您可以通过 ClientLogin 用户名/密码身份验证、AuthSubOAuth

有关 AuthSub、OAuth 和 ClientLogin 的详细信息,请参阅 Google Data API 身份验证概述

提示:该 API 支持 SSL (HTTPS)。如果您使用的是 AuthSub/OAuth,请确保指定 https://sites.google.com/feeds/ 范围,以便通过 SSL 请求 Feed。另请注意,对于 G Suite 网域时,“需要符合 SSL 规定”管理控制面板中的设置由 API 支持。您可以强制所有 通过调用 client.useSsl(); 通过 HTTPS 发送 API 请求。

用于网络应用程序的 AuthSub

网络应用的 AuthSub 身份验证应该由需要 验证其用户的身份。运营商无需获取 Google 协作平台用户的用户名和密码,只需 AuthSub 令牌为必填项。

查看关于将 AuthSub 加入 Web 应用的说明

请求一次性令牌

当用户首次访问您的应用时,他们需要进行身份验证。通常,开发者会输出一些文本和一个指向用户的链接 到 AuthSub 审批页面,以验证用户身份并请求对其文档的访问权限。Google 数据 Java 客户端库提供了一个函数, 生成此网址。以下代码设置了一个指向 AuthSubRequest 页面的链接。

import com.google.gdata.client.*;

String nextUrl = "http://www.example.com/welcome.jsp";
String scope = "https://sites.google.com/feeds/";
boolean secure = true;
boolean session = true;
String authSubUrl = AuthSubUtil.getRequestUrl(nextUrl, scope, secure, session);

如要对 G Suite 托管网域中的用户进行身份验证,请按以下步骤操作:

import com.google.gdata.client.*;

String hostedDomain = "example.com";
String nextUrl = "http://www.example.com/welcome.jsp";
String scope = "https://sites.google.com/feeds/";  // SSL is also supported
boolean secure = true;
boolean session = true;
String authSubUrl = AuthSubUtil.getRequestUrl(hostedDomain, nextUrl, scope, secure, session);

getRequestUrl() 方法采用多个参数(与 AuthSubRequest 处理程序使用的查询参数对应):

  • next 网址 - Google 将重定向到的网址 在用户登录其账号并授予访问权限后; 上例中的 http://www.example.com/welcome.jsp
  • 范围 - 上例中的 https://sites.google.com/feeds/
  • 一个布尔值,指示是否在注册模式下使用令牌;上例中的 false
  • 第二个布尔值,指示之后是否用令牌交换会话令牌;上例中的 true

升级为会话令牌

请参阅将 AuthSub 与 Google Data API 客户端库搭配使用

检索有关会话令牌的信息

请参阅将 AuthSub 与 Google Data API 客户端库搭配使用

撤消会话令牌

请参阅将 AuthSub 与 Google Data API 客户端库搭配使用

用于网络或安装版/移动应用的 OAuth

OAuth 可用作 AuthSub 的替代方案,适用于 Web 应用。 OAuth 类似于使用 AuthSub 的安全和注册模式 因为所有数据请求都必须进行数字签名,并且您必须注册自己的域名。

查看将 OAuth 加入已安装应用的说明

安装版/移动应用程序的 ClientLogin

ClientLogin 应由需要 验证其用户的身份。首次运行时,您的应用会提示用户输入其用户名/密码。在后续请求中 引用了身份验证令牌。

查看关于将 ClientLogin 整合到已安装的应用的说明

要使用 ClientLogin,请调用 setUserCredentials() SitesService 对象的方法,该方法继承自 GoogleService。指定用户的电子邮件地址和密码 您的客户端所代表的哪个账号发出请求。例如:

SitesService client = new SitesService("yourCo-yourAppName-v1");
client.setUserCredentials("example@gmail.com", "pa$$word");

提示:在您的应用首次成功对用户进行身份验证后,请将身份验证令牌存储在 供日后使用。无需在每次运行应用时都提示用户输入密码。 如需了解详情,请参阅调用身份验证令牌

如需详细了解如何在 Java 应用中使用 Dialogflow,请参阅将 Dialogflow 与 Google Data API 客户端库搭配使用

返回页首

站点 Feed

网站 Feed 可用于列出用户拥有或有权查看的 Google 协作平台。 该工具还可用于修改现有网站的名称。对于 G Suite 网域,它还可用于创建和/或复制 。

列出网站

要查询网站 Feed,请向网站 Feed 网址发送 HTTP GET

https://sites.google.com/feeds/site/site/

在 Java 客户端中,您可以使用 SiteFeedSiteEntry 类来 与网站 Feed 相关联:

public String getSiteFeedUrl() {
  String domain = "site";  // OR if the Site is hosted on G Suite, your domain (e.g. example.com)
  return "https://sites.google.com/feeds/site/" + domain + "/";
}

public void getSiteFeed() throws IOException, ServiceException {
  SiteFeed siteFeed = client.getFeed(new URL(getSiteFeedUrl()), SiteFeed.class);
  for (SiteEntry entry : siteFeed.getEntries()){
    System.out.println("title: " + entry.getTitle().getPlainText());
    System.out.println("site name: " + entry.getSiteName().getValue());
    System.out.println("theme: " + entry.getTheme().getValue());
    System.out.println("");
  }
}

以上代码段会输出网站的标题、网站名称和主题。其他 getter 适用于 访问 Feed 中的其他房源。

创建新网站

注意:此功能仅适用于 G Suite 网域。

您可以通过创建新的 SiteEntry 并调用客户端的 insert() 方法。

此示例创建了一个主题为“可选广告”的全新网站(可选设置),并提供 网站名称(必填)和说明(选填):

public String getSiteFeedUrl() {
  String domain = "example.com";
  return "https://sites.google.com/feeds/site/" + domain + "/";
}

public SiteEntry createSite(String title, String summary, String theme, String tag)
    throws MalformedURLException, IOException, ServiceException {
  SiteEntry entry = new SiteEntry();
  entry.setTitle(new PlainTextConstruct(title));
  entry.setSummary(new PlainTextConstruct(summary));

  Theme tt = new Theme();
  tt.setValue(theme);
  entry.setTheme(tt);

  entry.getCategories().add(new Category(TagCategory.Scheme.TAG, tag, null));

  return client.insert(new URL(getSiteFeedUrl()), entry);
}

SiteEntry newSiteEntry = createSite("My Site Title", "summary for site", "slate", "tag");

以上请求将在 G Suite 网域 example.com 下创建一个新网站。 因此,该网站的网址为 https://sites.google.com/a/example.com/my-site-title。

如果网站成功创建,服务器将会返回 SiteEntry 对象,其中填充了由服务器添加的元素:指向网站的链接、指向网站的 ACL 供稿的链接、 例如网站名称、标题、摘要等。

复制网站

注意:此功能仅适用于 G Suite 网域。

复制网站与创建新网站类似。不同之处在于,您需要设置一个 链接(包含要复制的网站的自链接)。SiteEntry 以下是复制创建新网站部分中创建的网站的示例:

public SiteEntry copySite(String title, String summary, String sourceHref)
    throws MalformedURLException, IOException, ServiceException {
  SiteEntry entry = new SiteEntry();
  entry.setTitle(new PlainTextConstruct(title));
  entry.setSummary(new PlainTextConstruct(summary));
  entry.addLink(SitesLink.Rel.SOURCE, Link.Type.ATOM, sourceHref);

  return client.insert(new URL(getSiteFeedUrl()), entry);
}

String sourceHref = newSiteEntry.getLink(SitesLink.Rel.SOURCE, Link.Type.ATOM).getHref();
SiteEntry myTwin = copySite("Duplicate Site", "A copy", sourceHref);

要点:

  • 只能复制经过身份验证的用户拥有的网站和网站模板。
  • 也可以复制网站模板。如果“将此网站发布为模板”选项,则表示此网站是一个模板。设置。
  • 您可以从其他网域复制网站,前提是您已被列为源网站的所有者。

更新网站的元数据

要重命名网站、更改其主题、类别标签或摘要,您需要先提取包含相关网站的 SiteEntry, 修改一个或多个属性,然后调用 SiteEntryupdate() 方法。 下例修改了以前网站的主题并重命名了该网站:

myTwin.setTitle(new PlainTextConstruct("better-title"));

Theme theme = myTwin.getTheme();
theme.setValue('iceberg');
myTwin.setTheme(theme);

myTwin.getCategories().add(new Category(TagCategory.Scheme.TAG, "newTag", null));

SiteEntry updatedSiteEntry = myTwin.update();

System.out.println(updatedSiteEntry.getTitle().getPlainText();

网址映射

通过网址映射,Google 协作平台用户可以将自己的网域映射到 Google 协作平台。例如:http://www.mydomainsite.com 可以代替 http://sites.google.com/a/domain.com/mysite。根据网站的托管位置,您可以手动修改 网站的网址映射有关详情,请参阅我们的帮助中心文章。

提取网站的网址映射

若要返回网站网址映射,请使用 with-mappings=true 参数提取网站条目/Feed:

SiteQuery query = new SiteQuery(new URL("https://sites.google.com/feeds/site/siteName"));
query.setWithMappings(true);

SiteFeed feed = service.getFeed(query, SiteFeed.class);
for (SiteEntry entry : feed.getEntries()) {
  System.out.println("Mappings for '" + entry.getSiteName().getValue() + "':");
  for (Link link : entry.getWebAddressMappingLinks()) {
    System.out.println("  " + link.getHref());
  }
}

现有映射将显示为带有 rel='webAddressMapping' 的 link。例如,在上面的示例中 有三个 webAddressMapping 指向该网站 http://sites.google.com/site/myOtherTestSite

修改网址映射

注意:所有 GET/POST/PUT 操作在工作时都应指定 with-mappings=true 参数 以及网址映射如果缺少此参数,将不会在网站条目中返回 webAddressMapping (GET),也不会考虑 (在条目中更新/移除 (PUT) 映射时)。

要添加、更新或删除映射,只需在创建新网站更新网站的元数据。网站 Feed URI 中必须包含 with-mappings=true 参数。 注意:要更新地址映射,您必须是网站管理员;如果是 G Suite 托管的网站,则您必须是网域管理员。

例如,以下请求将 http://www.mysitemapping.com 映射更新为 http://www.my-new-sitemapping.com, 并通过在条目中保留链接来移除 http://www.mysitemapping2.com

SiteEntry entry = client.getEntry(new URL("https://sites.google.com/feeds/site/site/siteName?with-mappings=true"), SiteEntry.class);

// Modify mappings (remove all mappings, add some of them again, add modified mappings)
entry.removeLinks(SitesLink.Rel.WEBADDRESSMAPPING, Link.Type.HTML);
entry.addLink(SitesLink.Rel.WEBADDRESSMAPPING, Link.Type.HTML, "http://www.my-new-sitemapping.com");

// Update the entry with the mappings.
entry.update();

请注意,您也可以在创建/复制网站时指定网址映射。

返回页首

活动 Feed

您可以通过提取活动供稿来提取网站的近期活动(更改)。系统会 活动供稿包含对网站所做的更改的相关信息。

要查询活动供稿,请向活动供稿网址发送 HTTP GET

https://sites.google.com/feeds/activity/site/siteName

在 Java 客户端中,使用 ActivityFeed 类返回 ActivityEntry 对象:

public String buildActivityFeedUrl() {
  String domain = "site";  // OR if the Site is hosted on G Suite, your domain (e.g. example.com)
  String siteName = "mySite";
  return "https://sites.google.com/feeds/activity/" + domain + "/" + siteName + "/";
}

public void getActivityFeed() throws IOException, ServiceException {
  ActivityFeed activityFeed = client.getFeed(new URL(buildActivityFeedUrl()), ActivityFeed.class);
  for (BaseActivityEntry<?> entry : activityFeed.getEntries()){
    System.out.println(entry.getSummary().getPlainText());
    System.out.println(" revisions link: " + entry.getRevisionLink().getHref());
  }
}

注意:您必须是网站的协作者或所有者才能访问此 Feed。 您的客户端必须使用 AuthSub、OAuth 或 ClientLogin 令牌进行身份验证。请参阅对 Google 协作平台服务进行身份验证

返回页首

修订版本 Feed

如需提取任何内容条目的修订历史记录,请向该条目的修订链接发送 HTTP GET

https://sites.google.com/feeds/revision/site/siteName/CONTENT_ENTRY_ID

下例会查询内容 Feed,然后提取第一个内容条目的修订版本 Feed:

ContentFeed contentFeed = client.getFeed(new URL(buildContentFeedUrl()), ContentFeed.class);
URL revisionFeedUrl = new URL(contentFeed.getEntries().get(0).getRevisionLink().getHref()); // use first entry

public void getRevisionFeed(String revisionFeedUrl) throws IOException, ServiceException {
  RevisionFeed revisionFeed = client.getFeed(revisionFeedUrl, RevisionFeed.class);
  for (BaseContentEntry<?> entry : revisionFeed.getEntries()){
    System.out.println(entry.getTitle().getPlainText());
    System.out.println(" updated: " + entry.getUpdated().toUiString() + " by " +
        entry.getAuthors().get(0).getEmail());
    System.out.println(" revision #: " + entry.getRevision().getValue());
  }
}

注意:您必须是网站的协作者或所有者才能访问此 Feed。 您的客户端必须使用 AuthSub、OAuth 或 ClientLogin 令牌进行身份验证。请参阅对 Google 协作平台服务进行身份验证

返回页首

内容 Feed

检索内容 Feed

内容 Feed 列出了网站的最新内容。向内容 Feed 网址发送 HTTP GET 即可访问此模块:

https://sites.google.com/feeds/content/site/siteName
Feed 参数说明
sitesite”或您的 G Suite 托管网域的域名(例如 example.com)。
siteName您网站的网络空间名称;(例如 mySite)。

提取内容 Feed 的示例:

public String buildContentFeedUrl() {
  String domain = "site";  // OR if the Site is hosted on G Suite, your domain (e.g. example.com)
  String siteName = "mySite";
  return "https://sites.google.com/feeds/content/" + domain + "/" + siteName + "/";
}

ContentFeed contentFeed = client.getFeed(new URL(buildContentFeedUrl()), ContentFeed.class);

生成的 contentFeed 是一个 ContentFeed 对象,其中包含来自服务器的响应。每个条目 的 contentFeed 表示用户网站中的其他网页或项。ContentFeed将包含不同类型的 共 个对象,所有对象均继承自 BaseContentEntryListItemEntryListPageEntryAttachmentEntryWebAttachmentEntryFileCabinetPageEntryAnnouncementsPageEntryAnnouncementEntryWebPageEntryCommentEntry

下例展示了如何在 ContentFeed 中列出不同类型的条目。 每种类型的条目都包含不同的属性,但此处并未输出所有属性。

public String getContentBlob(BaseContentEntry<?> entry) {
 return ((XhtmlTextConstruct) entry.getTextContent().getContent()).getXhtml().getBlob();
}

// Extracts an entry's numeric ID.
private String getEntryId(String selfLink) {
  return selfLink.substring(selfLink.lastIndexOf("/") + 1);
}

public void printContentEntries(ContentFeed contentFeed) {
  System.out.println("Listing all WebPageEntry:");
  for (WebPageEntry entry : contentFeed.getEntries(WebPageEntry.class)) {
    System.out.println(" title: " + entry.getTitle().getPlainText());
    System.out.println(" id: " + getEntryId(entry));
    if (entry.getParentLink() != null) {
      System.out.println(" parent id: " + getEntryId(entry.getParentLink().getHref()));
    }
    System.out.println(" author: " + entry.getAuthors().get(0).getEmail());
    System.out.println(" content: " + getContentBlob(entry));
  }

  System.out.println("Listing all ListPageEntry:");
  for (ListPageEntry entry : contentFeed.getEntries(ListPageEntry.class)) {
    System.out.println(" title: " + entry.getTitle().getPlainText());
    System.out.println(" id: " + getEntryId(entry));
    for (Column col : entry.getData().getColumns()) {
      System.out.print(" [" + col.getIndex() + "] " + col.getName() + "\t");
    }
  }

  for (ListItemEntry entry : contentFeed.getEntries(ListItemEntry.class)) {
    for (Field field : entry.getFields()) {
      System.out.print(" [" + field.getIndex() + "] " + field.getValue() + "\t");
    }
    System.out.println("\n");
  }

  System.out.println("Listing all FileCabinetPageEntry:");
  for (FileCabinetPageEntry entry : contentFeed.getEntries(FileCabinetPageEntry.class)) {
    System.out.println(" title: " + entry.getTitle().getPlainText());
    System.out.println(" id: " + getEntryId(entry));
    System.out.println(" content: " + getContentBlob(entry));
  }

  System.out.println("Listing all CommentEntry:");
  for (CommentEntry entry : contentFeed.getEntries(CommentEntry.class)) {
    System.out.println(" in-reply-to: " + entry.getInReplyTo().toString());
    System.out.println(" content: " + getContentBlob(entry));
  }

  System.out.println("Listing all AnnouncementsPageEntry:");
  for (AnnouncementsPageEntry entry : contentFeed.getEntries(AnnouncementsPageEntry.class)) {
    System.out.println(" title: " + entry.getTitle().getPlainText());
    System.out.println(" id: " + getEntryId(entry));
    System.out.println(" content: " + getContentBlob(entry));
  }

  System.out.println("Listing all AnnouncementEntry:");
  for (AnnouncementEntry entry : contentFeed.getEntries(AnnouncementEntry.class)) {
    System.out.println(" title: " + entry.getTitle().getPlainText());
    System.out.println(" id: " + getEntryId(entry));
    if (entry.getParentLink() != null) {
      System.out.println(" parent id: " + getEntryId(entry.getParentLink().getHref()));
    }
    System.out.println(" draft?: " + entry.isDraft());
    System.out.println(" content: " + getContentBlob(entry));
  }

  System.out.println("Listing all AttachmentEntry:");
  for (AttachmentEntry entry : contentFeed.getEntries(AttachmentEntry.class)) {
    System.out.println(" title: " + entry.getTitle().getPlainText());
    System.out.println(" id: " + getEntryId(entry));
    if (entry.getParentLink() != null) {
      System.out.println(" parent id: " + getEntryId(entry.getParentLink().getHref()));
    }
    if (entry.getSummary() != null) {
      System.out.println(" description: " + entry.getSummary().getPlainText());
    }
    System.out.println(" revision: " + entry.getRevision().getValue());
    MediaContent content = (MediaContent) entry.getContent();
    System.out.println(" src: " + content.getUri());
    System.out.println(" content type: " + content.getMimeType().getMediaType());
  }

  System.out.println("Listing all WebAttachmentEntry:");
  for (WebAttachmentEntry entry : contentFeed.getEntries(WebAttachmentEntry.class)) {
    System.out.println(" title: " + entry.getTitle().getPlainText());
    System.out.println(" id: " + getEntryId(entry));
    if (entry.getParentLink() != null) {
      System.out.println(" parent id: " + getEntryId(entry.getParentLink().getHref()));
    }
    if (entry.getSummary() != null) {
      System.out.println(" description: " + entry.getSummary().getPlainText());
    }
    System.out.println(" src: " + ((MediaContent) entry.getContent()).getUri());
  }
}

注意:此 Feed 不一定要求进行身份验证;具体取决于网站的共享权限。 如果网站为非公开网站,则您的客户端必须使用 AuthSub、OAuth 或 ClientLogin 令牌进行身份验证。请参阅 对 Google 协作平台服务进行身份验证

内容 Feed 查询示例

您可以使用一些标准 Google Data API 查询参数来搜索内容 Feed。 以及传统版协作平台 API 特有的设置。如需了解更多详细信息和所支持参数的完整列表,请参阅 参考指南

注意:本部分中的示例使用检索内容 Feed 中的 buildContentFeedUrl() 方法。

检索特定条目种类

如需仅提取特定类型的条目,请使用 kind 参数。以下示例仅返回 attachment 条目:

ContentQuery query = new ContentQuery(new URL(buildContentFeedUrl()));
query.setKind("webpage");
ContentFeed contentFeed = client.getFeed(query, ContentFeed.class);
for (AttachmentEntry entry : contentFeed.getEntries(AttachmentEntry.class)) {
  System.out.println(entry.getTitle().getPlainText());
}

如需返回多个条目类型,请使用“,”分隔每个 kind。此示例返回 filecabinetlistpage 个条目:

URL url = new URL(buildContentFeedUrl() + "?kind=filecabinet,listpage");
ContentFeed contentFeed = client.getFeed(url, ContentFeed.class);
for (FileCabinetPageEntry entry : contentFeed.getEntries(FileCabinetPageEntry.class)) {
  System.out.println(" title: " + entry.getTitle().getPlainText());
}
for (ListPageEntry entry : contentFeed.getEntries(ListPageEntry.class)) {
  System.out.println(" title: " + entry.getTitle().getPlainText());
}

按路径检索网页

如果您知道 Google 网站中某个网页的相对路径,可以使用 path 参数提取该特定网页。 本示例将返回位于 http://sites.google.com/site/siteName/path/to/the/page

ContentQuery query = new ContentQuery(new URL(buildContentFeedUrl()));
query.setPath("/path/to/the/page");
ContentFeed contentFeed = client.getFeed(query, ContentFeed.class);
for (BaseContentEntry<?> entry : contentFeed.getEntries()) {
  System.out.println(" title: " + entry.getTitle().getPlainText());
}

检索父页面下的所有条目

如果您知道某个网页的内容条目 ID(例如下例中的“1234567890”),则可以使用 parent 参数 以提取其所有子条目(如果有):

ContentQuery query = new ContentQuery(new URL(buildContentFeedUrl()));
query.setParent("1234567890");
ContentFeed contentFeed = client.getFeed(query, ContentFeed.class);

如需了解其他参数,请参阅参考指南

返回页首



创建内容

注意:在为网站创建内容之前,请确保您已在客户端中设置您的网站。
client.site = "siteName";

您可以通过发送 HTTP POST 来创建新内容(网页、列表页、文件箱式页面、公告页等), 添加到内容 Feed 中:

https://sites.google.com/feeds/content/site/siteName

如需查看支持节点类型的列表,请参阅参考指南中的 kind 参数。

创建新的内容 / 页面

此示例会在网站的顶级目录下创建一个新的 webpage,并为页面正文添加一些 XHTML, 并将标题标题设置为“New WebPage Title”:

private void setContentBlob(BaseContentEntry<?> entry, String pageContent) {
  XmlBlob xml = new XmlBlob();
  xml.setBlob(pageContent);
  entry.setContent(new XhtmlTextConstruct(xml));
}

public WebPageEntry createWebPage(String title, String content)
    throws MalformedURLException, IOException, ServiceException {
  WebPageEntry entry = new WebPageEntry();
  entry.setTitle(new PlainTextConstruct(title));

  setContentBlob(entry, content); // Entry's HTML content

  return client.insert(new URL(buildContentFeedUrl()), entry);
}

WebPageEntry createdEntry = createWebPage("New Webpage Title", "<b>HTML content</b>");
System.out.println("Created! View at " + createdEntry.getHtmlLink().getHref());

如果请求成功,createdEntry 会包含在服务器上创建的条目的副本。

在自定义网址路径下创建项/网页

默认情况下,上述示例会在网址下方创建 http://sites.google.com/site/siteName/new-webpage-title和 网页标题为“新网页标题”。也就是说,系统会将网址的 <atom:title> 标准化为 new-webpage-title。 如需自定义页面的网址路径,您可以设置 <sites:pageName> 元素。

本示例创建了一个标题为“File Storage”的新 filecabinet 页面,但创建了该页面 在网址 http://sites.google.com/site/siteName/files 下方 (而非 http://sites.google.com/site/siteName/file-storage) 方法是指定<sites:pageName>元素

public FileCabinetPageEntry createFileCabinetPage(String title, String content, String customPageName)
    throws MalformedURLException, IOException, ServiceException {
  FileCabinetPageEntry entry = new FileCabinetPageEntry();
  entry.setTitle(new PlainTextConstruct(title));

  setContentBlob(entry, content); // Entry's HTML content

  entry.setPageName(new PageName(customPageName)); // Upload to a custom page path

  return client.insert(new URL(buildContentFeedUrl()), entry);
}

FileCabinetPageEntry createdEntry = createFileCabinetPage("File Storage", "<b>HTML content</b>", "files");
System.out.println("Created! View at " + createdEntry.getHtmlLink().getHref());

在命名网页网址路径时,服务器会遵循以下优先规则:

  1. <sites:pageName>(如果存在)。必须满足 a-z, A-Z, 0-9, -, _
  2. <atom:title>,如果 pageName 不存在,则不得为 null。规范化是去除 + 将空格收缩为“-”和 移除与 a-z, A-Z, 0-9, -, _ 不匹配的字符。

创建子页面

要在父页面下创建子页面(子页面),您必须在条目中设置父链接。该链接的 href 属性指向 父节点的自链接

public AnnouncementEntry postAnnouncement(String title, String content, AnnouncementsPageEntry parentPage)
    throws MalformedURLException, IOException, ServiceException {
  AnnouncementEntry entry = new AnnouncementEntry();
  entry.setTitle(new PlainTextConstruct(title));

  setContentBlob(entry, content); // Entry's HTML content

  // Set the entry's parent link to create the announcement under that page.
  entry.addLink(SitesLink.Rel.PARENT, Link.Type.ATOM, parentPage.getSelfLink().getHref());

  return client.insert(new URL(buildContentFeedUrl()), entry);
}

ContentFeed contentFeed = client.getFeed(new URL(buildContentFeedUrl() + "?kind=announcementspage"), ContentFeed.class);

AnnouncementEntry createdEntry = postAnnouncement("Party!!", "My place, this weekend", contentFeed.getEntries().get(0));
System.out.println("New post by " + createdEntry.getAuthors().get(0).getName());

上面的示例在以下位置找到的第一个公告页面下创建了一个新的 announcement: 用户的内容 Feed。通告标题设为“Party!!”并将内容设为“我的地点,本周末”。

页面模板

创建页面模板

页面模板的创建流程与创建新项/页面创建子页面。区别在于,区别在于添加了 category,并将字词和标签设置为“http://schemas.google.com/g/2005#template” “template”和“template”

此示例将创建一个新的 webpage 模板。

// The template webpage entry.
WebPageEntry entry = new WebPageEntry();

// Set title and content.
entry.setTitle(new PlainTextConstruct("Page template title"));
XmlBlob xml = new XmlBlob();
xml.setBlob("Content for page template");
entry.setContent(new XhtmlTextConstruct(xml));

// Set the template category
Category TEMPLATE_CATEGORY = new Category(TemplateCategory.Scheme.LABELS,
    TemplateCategory.Term.TEMPLATE, TemplateCategory.Label.TEMPLATE);
entry.getCategories().add(TEMPLATE_CATEGORY);

// Insert the template webpage entry.
WebPageEntry createdEntry = client.insert(new URL("https://sites.google.com/feeds/content/site/siteName"), entry);

通过模板创建页面

与创建页面模板类似,您可以通过使用 rel='http://schemas.google.com/sites/2008#template' 添加 <link> 来通过模板实例化新页面指向 网页模板的页内链接。

此示例会创建一个新的 filecabinet 模板,然后基于该模板实例化一个新的 filecabinet 页面。

URL feedUrl = new URL("https://sites.google.com/feeds/content/site/siteName");

// 1. Create file cabinet page template
FileCabinetPageEntry inputTemplateEntry = new FileCabinetPageEntry();
inputTemplateEntry.setTitle(new PlainTextConstruct("File cabinet page template title"));
XmlBlob xml = new XmlBlob();
xml.setBlob("Content for page template");
inputTemplateEntry.setContent(new XhtmlTextConstruct(xml));

// Set the template category
Category TEMPLATE_CATEGORY = new Category(TemplateCategory.Scheme.LABELS,
    TemplateCategory.Term.TEMPLATE, TemplateCategory.Label.TEMPLATE);
inputTemplateEntry.getCategories().add(TEMPLATE_CATEGORY);

// 2. Create file cabinet page template instance
FileCabinetPageEntry templateEntry = client.insert(feedUrl, inputTemplateEntry);

// Specify link to the page template
FileCabinetPageEntry templateInstanceEntry = new FileCabinetPageEntry();
templateInstanceEntry.setTitle(new PlainTextConstruct("File cabinet template instance"));
templateInstanceEntry.addLink(new Link(SitesLink.Rel.TEMPLATE, Link.Type.ATOM, templateEntry.getSelfLink().getHref()));

FileCabinetPageEntry createdFileCabinetFromTemplate =  client.insert(feedUrl, templateInstanceEntry);

注意:尽管模板定义了 <category>,包括您的 条目。另请注意,如果您添加 <content> 元素,服务器将拒绝该元素。

上传文件

与在 Google 协作平台中一样,该 API 支持将附件上传至文件箱式页面或父页面。

如需向父级上传附件,请向内容 Feed 网址发送 HTTP POST 请求:

https://sites.google.com/feeds/content/site/siteName

所有类型的附件都必须上传到父页面。因此,您应在 AttachmentEntry 上设置父级链接。 或 WebAttachmentEntry 对象。如需了解详情,请参阅创建子页面

正在上传附件

此示例将 PDF 文件上传到用户内容 Feed 中找到的第一个 FileCabinetPageEntry。 系统将创建标题为“使用入门”的附件以及(可选)说明“HR 包”。

MimetypesFileTypeMap mediaTypes = new MimetypesFileTypeMap();
mediaTypes.addMimeTypes("application/msword doc");
mediaTypes.addMimeTypes("application/vnd.ms-excel xls");
mediaTypes.addMimeTypes("application/pdf pdf");
mediaTypes.addMimeTypes("text/richtext rtx");
// ... See a more complete list of mime types in the SitesHelper.java

public AttachmentEntry uploadAttachment(File file, BasePageEntry<?> parentPage,
    String title, String description) throws IOException, ServiceException {
  AttachmentEntry newAttachment = new AttachmentEntry();
  newAttachment.setMediaSource(new MediaFileSource(file, mediaTypes.getContentType(file)));
  newAttachment.setTitle(new PlainTextConstruct(title));
  newAttachment.setSummary(new PlainTextConstruct(description));
  newAttachment.addLink(SitesLink.Rel.PARENT, Link.Type.ATOM, parentPage.getSelfLink().getHref());

  return client.insert(new URL(buildContentFeedUrl()), newAttachment);
}

ContentFeed contentFeed = client.getFeed(new URL(buildContentFeedUrl() + "?kind=filecabinet"), ContentFeed.class);
FileCabinetPageEntry parentPage = contentFeed.getEntries(FileCabinetPageEntry.class).get(0);

AttachmentEntry attachment = uploadAttachment(
    new File("/path/to/your/file.pdf"), parentPage, "Getting Started", "HR packet");
System.out.println("Uploaded!");

如果上传成功,attachment 将包含已创建的附件条目的副本。

将附件上传到文件夹

如需将附件上传到 FileCabinetPageEntry 中的现有文件夹,请添加一个带有“term”的类别属性设置为文件夹名称。 例如,在 uploadAttachment() 中添加以下代码行:

newAttachment.getCategories().add(new Category("http://schemas.google.com/sites/2008#folder", "FolderName"));

Web 附件

Web 附件是一种特殊类型的附件。从本质上讲,这些文件是指向网络上其他文件的链接 您可以将其添加到文件柜列表中。此功能类似于“通过网址添加文件”上传方法。

注意:网络附件只能在文件箱式页面中创建。但不能上传到其他类型的网页。

此示例会在用户的内容 Feed 中找到的第一个 FileCabinetPageEntry 下创建 WebAttachmentEntry。 其标题和(可选)说明设置为“GoogleLogo”和 'nice color' [漂亮颜色]。

public WebAttachmentEntry uploadWebAttachment(String contentUrl, FileCabinetPageEntry filecabinet,
    String title, String description) throws MalformedURLException, IOException, ServiceException {
  MediaContent content = new MediaContent();
  content.setUri(contentUrl);

  WebAttachmentEntry webAttachment = new WebAttachmentEntry();
  webAttachment.setTitle(new PlainTextConstruct(title));
  webAttachment.setSummary(new PlainTextConstruct(description));
  webAttachment.setContent(content);
  webAttachment.addLink(SitesLink.Rel.PARENT, Link.Type.ATOM,
      filecabinet.getSelfLink().getHref());

  return client.insert(new URL(buildContentFeedUrl()), webAttachment);
}

ContentFeed contentFeed = client.getFeed(new URL(buildContentFeedUrl() + "?kind=filecabinet"), ContentFeed.class);
FileCabinetPageEntry parentPage = contentFeed.getEntries(FileCabinetPageEntry.class).get(0);

WebAttachmentEntry webAttachment =
    uploadWebAttachment("http://www.google.com/images/logo.gif", parentPage, "Google's Logo", "nice colors");
System.out.println("Web attachment created!");

POST 会在用户的文件柜中创建一个链接,指向位于“http://www.google.com/images/logo.gif”的图片。

返回页首



更新内容

更新网页的元数据和/或 HTML 内容

任何 BaseContentEntry 类型的元数据(标题、pageName 等)和网页内容均可修改 并使用该条目的 update() 方法。这将向条目的 edit 发送 HTTP PUT 请求 链接。

以下示例展示了如何更新 ListPageEntry 并进行了以下更改:

  • 标题已修改为“已更新标题”
  • 该网页的 HTML 内容已更新为“<p>已更新的 HTML 内容</p>”
  • 列表的第一列标题将更改为“所有者”
ContentFeed contentFeed = client.getFeed(
    new URL(buildContentFeedUrl() + "?kind=listpage"), ContentFeed.class);
ListPageEntry listPage = contentFeed.getEntries(ListPageEntry.class).get(0); // Update first list page found

// Update title
listPage.setTitle(new PlainTextConstruct("Updated Title"));

// Update HTML content
XmlBlob xml = new XmlBlob();
xml.setBlob("<p>Updated HTML Content</p>");
listPage.setContent(new XhtmlTextConstruct(xml));

// Change first column's heading
listPage.getData().getColumns().get(0).setName("Owner");

// listPage.setPageName(new PageName("new-page-path"));  // You can also change the page's URL path

ListPageEntry updatedEntry = listPage.update();

System.out.println("ListPage updated!");

更新附件文件内容

对于 AttachmentEntry,您还可以通过设置条目的 MediaSource,然后使用 条目的 updateMedia(boolean) 方法。

此示例将更新现有附件的内容:

public AttachmentEntry updateFile(AttachmentEntry entry, File newFile)
    throws IOException, ServiceException {
  // See Uploading Attachments for the definition of mediaTypes.
  entry.setMediaSource(new MediaFileSource(newFile, mediaTypes.getContentType(newFile)));
  return entry.updateMedia(false);
}

该示例向条目的 edit-media 链接发送 HTTP PUT 请求。返回的 AttachmentEntry 将包含更新后的内容。

更新附件元数据 + 内容

您可以使用 updateMedia() 方法在同一调用中更新附件的元数据及其内容。 您可以只更新文件内容和/或元数据。

本示例将附件标题更改为“新标题”,更新其说明,并使用新的 .zip 文件替换其文件内容。 由于请求包含新的文件内容,因此会使用 AttachmentEntryupdateMedia()

public AttachmentEntry updateAttachment(AttachmentEntry entry, File newFile, String newTitle, String newDescription)
    throws IOException, ServiceException  {
  // See Uploading Attachments for the definition of mediaTypes.
  entry.setMediaSource(new MediaFileSource(newFile, mediaTypes.getContentType(newFile)));
  entry.setTitle(new PlainTextConstruct(newTitle));
  entry.setSummary(new PlainTextConstruct(newDescription));

  return entry.updateMedia(true);
}

ContentFeed contentFeed = client.getFeed(
    new URL(buildContentFeedUrl() + "?kind=attachment&max-results=1"), ContentFeed.class);
AttachmentEntry attachment = contentFeed.getEntries(AttachmentEntry.class).get(0); // Update first attachment found

AttachmentEntry updatedAttachment = updateAttachment(attachment, new File("/path/to/file.zip"), "New Title", "better stuff");

返回页首



删除内容

要从 Google 协作平台中移除网页或项,请先检索内容条目,然后调用该条目的 delete()

entry.delete();

您还可以使用服务类的 delete() 方法,只需向其传递条目的 edit 链接和 ETag 值即可:

client.delete(entry.getEditLink().getHref(), "*"); // Note: using "*" may overwrite another client's changes.

如果条目已成功删除,服务器会返回 HTTP 200 OK 响应。

返回页首



下载附件

要下载 AttachmentEntry,请向该条目的 content src 链接发送 HTTP GET 请求。

此示例会下载在用户内容 Feed 中找到的第一个 AttachmentEntry 复制到目录“/path/to/save/file/”:

private void downloadFile(String downloadUrl, String fullFilePath) throws IOException, ServiceException {
  System.out.println("Downloading file from: " + downloadUrl);

  MediaContent mc = new MediaContent();
  mc.setUri(downloadUrl);
  MediaSource ms = service.getMedia(mc);

  InputStream inStream = null;
  FileOutputStream outStream = null;

  try {
    inStream = ms.getInputStream();
    outStream = new FileOutputStream(fullFilePath);

    int c;
    while ((c = inStream.read()) != -1) {
      outStream.write(c);
    }
  } finally {
    if (inStream != null) {
      inStream.close();
    }
    if (outStream != null) {
      outStream.flush();
      outStream.close();
    }
  }
}

public void downloadAttachment(AttachmentEntry entry, String directory) throws IOException, ServiceException {
  String url = ((OutOfLineContent) entry.getContent()).getUri();
  downloadFile(url, directory + entry.getTitle().getPlainText()); // Use entry's title for the save filename
}

ContentFeed contentFeed = client.getFeed(
    new URL(buildContentFeedUrl() + "?kind=attachment&max-results=1"), ContentFeed.class);

downloadAttachment(contentFeed.getEntries(AttachmentEntry.class).get(0), "/path/to/save/file/");
System.out.println("Downloaded.");

返回页首

ACL 供稿

共享权限 (ACL) 概览

ACL 供稿中的每个 ACL 条目代表一个特定实体的访问角色,这些实体可以是用户、用户群组、网域 或默认访问权限(即公共站点)。系统只会为拥有明确访问权限的实体显示条目 - 系统会显示一个条目 每个电子邮件地址面板。因此,系统不会显示网域管理员 即使他们对某网站拥有隐式访问权限,也是如此。

角色

角色元素表示实体可以拥有的访问权限级别。gAcl:role 元素有以下四个可能的值:

  • Reader - 查看者(等同于只读访问权限)。
  • writer - 协作者(等同于读/写权限)。
  • owner - 通常是网站管理员(相当于读/写权限)。

范围

范围元素表示具有此访问权限级别的实体。gAcl:scope 元素有四种可能的类型:

  • user - 电子邮件地址值,如“user@gmail.com”。
  • group - Google 群组电子邮件地址,例如“group@domain.com”。
  • domain - G Suite 域名,例如“domain.com”。
  • default - 只有一个可能的“default”类型范围(该范围没有任何值) (例如 <gAcl:scope type="default">)。此特定范围控制任何用户默认拥有的访问权限 放在公开网站上。

注意:域名不能包含 gAcl:role 值 设为“所有者”他们只能是读者或作者。

检索 ACL 供稿

AclFeedAclEntry 类可用于控制网站的共享 权限,并且可以使用服务类的 getFeed() 方法获取。

以下示例提取指定网站的 ACL 供稿,并输出 每个AclEntry

public String getAclFeedUrl(String siteName) {
  String domain = "site";  // OR if the Site is hosted on G Suite, your domain (e.g. example.com)
  return "https://sites.google.com/feeds/acl/site/" + domain + "/" + siteName + "/";
}

public void getAclFeed(String siteName) throws IOException, ServiceException {
  AclFeed aclFeed = client.getFeed(new URL(getAclFeedUrl(siteName)), AclFeed.class);
  for (AclEntry entry : aclFeed.getEntries()) {
    System.out.println(entry.getScope().getValue() + " (" + entry.getScope().getType() + ") : " +
                       entry.getRole().getValue());
  }
}

getAclFeed('my-site-name');

如果您使用的是 SiteFeed 中的条目,则每个 SiteEntry 都包含指向其 ACL Feed 的链接。 例如,以下代码段用于提取 SiteEntry 的 acl Feed:

String aclLink = siteEntry.getLink(SitesAclFeedLink.Rel.ACCESS_CONTROL_LIST, Link.Type.ATOM).getHref();
AclFeed aclFeed = client.getFeed(new URL(aclLink), AclFeed.class);

共享网站

注意:某些共享 ACL 只有在网域进行了配置的情况下才能实现 授予此类权限(例如,如果启用了 G Suite 网域与网域外的用户共享功能等)。

要使用 API 共享 Google 网站,您的客户端需要创建新的 AclEntry 并将其 POST 到服务器。

下面是一个添加“user@example.com”的示例以 reader 的形式访问以下网站:

AclRole role = new AclRole("reader");
AclScope scope = new AclScope(AclScope.Type.USER, "user@example.com");
AclEntry aclEntry = addAclRole(role, scope, entry);

public AclEntry addAclRole(AclRole role, AclScope scope, SiteEntry siteEntry)
    throws IOException, MalformedURLException, ServiceException  {
  AclEntry aclEntry = new AclEntry();
  aclEntry.setRole(role);
  aclEntry.setScope(scope);

  Link aclLink = siteEntry.getLink(SitesAclFeedLink.Rel.ACCESS_CONTROL_LIST, Link.Type.ATOM);
  return client.insert(new URL(aclLink.getHref()), aclEntry);
}

如需了解可能的 AclScope,请参阅 ACL Feed 概览部分 和 AclRoles 值。

群组和网域级别的共享

与单个用户共享网站类似,您可以通过 Google 群组或 G Suite 网域。

共享到群组电子邮件地址:

AclScope scope = new AclScope(AclScope.Type.GROUP, "group_name@example.com");

与整个网域共享:

AclScope scope = new AclScope(AclScope.Type.DOMAIN, "example.com");

只有 G Suite 网域以及托管网站的网域支持网域级共享。 例如,http://sites.google.com/a/domain1.com/siteA 只能与 domain1.com 共享整个协作平台,而非 domain2.com。会 未托管在 G Suite 网域上(例如 http://sites.google.com/site/siteB),则无法邀请网域。

修改共享权限

要访问网站上的现有共享权限,请先提取相关的 AclEntry,然后修改权限 ,然后调用 AclEntryupdate() 方法来修改服务器上的 ACL。

此示例修改了前面共享网站部分中的 aclEntry 示例, 方法是更新“user@example.com”成为 writer(协作者):

aclEntry.setRole(new AclRole("writer"));
AclEntry updatedAclEntry = aclEntry.update();

// Could also use the client's update method
// client.update(new URL(aclEntry.getEditLink().getHref()), aclEntry);

要详细了解 ETag,请参阅 Google Data API 参考指南

正在移除共享权限

如需移除共享权限,请先检索 AclEntry,然后调用其 delete() 方法:

aclEntry.delete();

// Could also use the client's delete method
// client.delete(new URL(aclEntry.getEditLink().getHref()), aclEntry);

要详细了解 ETag,请参阅 Google Data API 参考指南

返回页首

特殊主题

重新检索供稿或条目

如果要检索以前检索过的供稿或条目,可以告诉系统, 服务器将列表或条目发送至服务器,使其仅在自上次检索以来发生了更改。

为执行这种条件式检索,getFeed()getEntry() 方法都提供 一个接受 ETag 值或 If-Modified-Since 标头的 DateTime 对象的附加参数。 您可以从 entry.getEtag() 访问条目的 ETag。

下例对内容网页条目执行有条件检索:

String feedUrl = "https://sites.google.com/feeds/content/site/siteName/123456789";
WebPageEntry entry = client.getEntry(new URL(feedUrl), WebPageEntry.class, "\"GVQHSARDQyp7ImBq\"");

服务器收到此请求后,会检查您请求的项目是否与 您指定的 ETag。如果 ETag 匹配,则项目没有更改,且服务器返回 将抛出 HTTP 304 NotModifiedException 异常。

如果两个 ETag 不匹配,则表示该项自您上次请求后发生了修改,因此服务器会返回该项。

要详细了解 ETag,请参阅 Google Data API 参考指南

返回页首