Java 語言指南

重要事項:本文件是在 2012 年之前撰寫,驗證選項 (OAuth 1.0、AuthSub 和 ClientLogin) 中所述, 已正式淘汰 自 2012 年 4 月 20 日起,無法再使用。建議您遷移至 OAuth 2.0

Google Sites Data API 可讓用戶端應用程式存取、發布及修改 Google 協作平台中的內容。 用戶端應用程式也可以請求近期活動清單、擷取修訂版本記錄並下載附件。

除了提供 Sites Data API 功能的一些背景資訊之外,本指南也提供與 API 互動的範例 使用 Java 用戶端程式庫。如需設定用戶端程式庫的說明,請參閱 開始使用 Google Data Java 用戶端程式庫。如果你有興趣瞭解 如要進一步瞭解 Java 用戶端程式庫用來與傳統版協作平台 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)

安裝 .jars 後,您需要在專案中加入以下內容:

  1. java/lib/gdata-sites-2.0.jar - 本文 2.0 版適用於傳統版協作平台 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/ 取得 。SitesDemo.java 可讓使用者執行多項作業,示範傳統版協作平台 API 的使用方式。

請注意,您必須加入 java/sample/util/lib/sample-util.jar 才能執行範例。

開始自行啟動專案

提示:請參閱搭配使用 Eclipse 與 Google Data API,瞭解如何快速設定 Eclipse 外掛程式。

視應用程式需求而定,您需要數次匯入功能。建議您從下列匯入作業著手:

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 物件,代表與傳統版協作平台 API 的用戶端連線:

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

applicationName 引數應採用下列格式:company-applicationname-version。此參數是用於記錄。

注意:本指南的其餘部分假設您已在 client 變數中建立 SitesService

驗證傳統版協作平台 API

Java 用戶端程式庫可用於使用公開或私人動態饋給。Sites Data API 可讓您存取私人與公開的資料 資訊提供。舉例來說,您能夠讀取 「公開協作平台」,但「不更新」內容,但這個檔案需要經過驗證的用戶端。我們可以透過 ClientLogin 使用者名稱/密碼驗證、AuthSubOAuth

如要進一步瞭解 AuthSub、OAuth 和 ClientLogin,請參閱 Google Data API 驗證總覽

提示:這個 API 支援安全資料傳輸層 (HTTPS)。如果您使用 AuthSub/OAuth,請務必指定 一個 https://sites.google.com/feeds/ 範圍,用來要求透過安全資料傳輸層 (SSL) 提出動態饋給。另請注意 G Suite 網域,[要求 SSL]API 會遵循管理控制台中的設定。您可以強制 呼叫 client.useSsl(); 即可透過 HTTPS 要求 API。

適用於網頁應用程式的 AuthSub

網頁應用程式的 AuthSub 驗證應由用戶端應用程式使用, 驗證他們的 Google 帳戶使用者運算子不需存取 Google 協作平台使用者的使用者名稱和密碼。 必須提供 AuthSub 權杖。

查看將 AuthSub 整合至網頁應用程式的操作說明

要求單次使用權杖

使用者首次造訪您的應用程式時,需要進行驗證。一般而言,開發人員會輸出一些文字和一個連結,用於引導使用者前往 ,藉此驗證使用者並要求存取他們的文件。Google Data 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 處理常式使用的查詢參數):

  • 下一個網址 — 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 的替代方案,適用於網頁應用程式。 OAuth 類似於使用 AuthSub 的安全與註冊模式 因為所有資料要求都必須經過數位簽署,而且您必須註冊網域。

查看將 OAuth 整合至已安裝的應用程式的操作說明

已安裝/行動應用程式的 ClientLogin

應使用已安裝 ClientLogin 的已安裝應用程式或行動應用程式, 驗證他們的 Google 帳戶使用者首次執行時,應用程式會提示使用者輸入使用者名稱/密碼。在後續要求中 參照驗證權杖

查看將 ClientLogin 整合至已安裝應用程式的操作說明

如要使用 ClientLogin,請叫用 setUserCredentials() SitesService 物件方法 (繼承自 GoogleService。指定使用者的電子郵件地址和密碼 。例如:

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

提示:應用程式首次成功驗證使用者身分後,請將驗證權杖儲存在 以便日後使用因此每當應用程式執行時,便無須要求使用者提供密碼。 詳情請參閱呼叫驗證權杖

如要進一步瞭解如何在 Java 應用程式中使用 ClientLogin,請參閱使用 ClientLogin 搭配 Google Data API 用戶端程式庫

返回頁首

網站動態饋給

網站動態消息可用於列出使用者擁有的 Google 協作平台,或具備檢視權限。 您也可以使用這個指令碼修改現有網站的名稱。如果是 G Suite 網域,也可以用來建立和/或複製 網站的所有訪客。

列出網站

如要查詢網站動態饋給,請將 HTTP GET 傳送至網站動態饋給網址:

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

在 Java 用戶端中,您可以使用 SiteFeedSiteEntry 類別來執行作業 下列網站動態饋給:

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 適用於 存取動態饋給中的其他資源

建立新協作平台

注意:這項功能僅適用於 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);

重要事項:

  • 只能複製已驗證使用者擁有的網站和網站範本。
  • 也可以複製協作平台範本。如果「將這個協作平台發布為範本」已在 Google 協作平台設定頁面中勾選這項設定
  • 您可以從其他網域複製網站 (您必須是來源網站的擁有者)。

更新網站中繼資料

如要重新命名網站、變更主題、類別標記或摘要,請先擷取包含相關網站的 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 協作平台。例如:http://www.mydomainsite.com 可取代 http://sites.google.com/a/domain.com/mysite視網站的代管位置而定,您可以手動修改 來代表網站的網址對應詳情請參閱說明中心文章

擷取網站的網址對應

如要傳回網站的網址對應,請使用 with-mappings=true 參數擷取網站項目/動態饋給:

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 參數 網址對應。如果沒有這個參數,網站項目 (GET) 就不會傳回 webAddressMapping,也不會考慮該參數。 從項目更新/移除 (PUT) 對應時。

如要新增、更新或刪除對應關係,請在建立新網站時指定、變更或移除這類連結;或 更新網站中繼資料。網站動態饋給 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();

請注意,您也可以在建立/複製協作平台時指定網址對應。

返回頁首

活動動態消息

您可以擷取活動資訊提供,擷取網站的最近活動 (變更)。模型中的每個項目 活動資訊提供包含「網站」變更的資訊。

若要查詢活動動態消息,請將 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());
  }
}

注意:您必須是協作平台的協作者或擁有者,才能存取這份動態饋給。 您的用戶端必須使用 AuthSub、OAuth 或 ClientLogin 權杖進行驗證。請參閱驗證協作平台服務

返回頁首

修訂版本資訊提供

如要擷取任何內容項目的修訂版本記錄,請傳送 HTTP GET 至該項目的修訂版本連結:

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

這個範例會查詢內容資訊提供,然後擷取第一個內容項目的修訂資訊提供:

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());
  }
}

注意:您必須是協作平台的協作者或擁有者,才能存取這份動態饋給。 您的用戶端必須使用 AuthSub、OAuth 或 ClientLogin 權杖進行驗證。請參閱驗證協作平台服務

返回頁首

內容動態饋給

擷取內容動態饋給

內容資訊提供會列出網站的最新內容。如要存取這個外掛程式,請將 HTTP GET 傳送至內容動態饋給網址:

https://sites.google.com/feeds/content/site/siteName
動態饋給參數說明
sitesite」或是您 G Suite 代管網域的網域 (例如 example.com)。
siteName您網站的網頁空間名稱;(例如 mySite)。

擷取內容動態饋給的範例:

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);

產生的 contentFeedContentFeed 物件,內含伺服器的回應。每個項目 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());
  }
}

注意:這類動態饋給不一定需要驗證;以此為依據。 如果是非公開的網站,則您的用戶端必須使用 AuthSub、OAuth 或 ClientLogin 權杖進行驗證。詳情請見 驗證協作平台服務

內容動態饋給查詢範例

您可以使用部分標準 Google Data API 查詢參數搜尋內容動態饋給。 以及傳統版協作平台 API 的特定檔案如需詳細資訊和完整的支援參數清單,請參閱 參考指南

注意:本節中的範例使用「擷取內容動態饋給」中的 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。這個範例會傳回 filecabinet listpage 個項目:

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 內容資訊提供:

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> 元素。

這個範例會建立新的 filecabinet 頁面,標題為「File Storage」,但建立頁面時 在網址 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,則不得為空值。正規化為剪輯並將空白字元「-」收合和 移除不符合 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 使用者的內容資訊提供公告標題設為「派對!」然後寫成「我在這裡,本週末我的地點」的內容

頁面範本

建立頁面範本

建立頁面範本的程序和建立新項目/頁面建立子頁面。差別在於新增 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 支援將附件上傳到檔案櫃頁面或上層頁面。

如要將附件上傳到父項,請傳送 HTTP POST 要求至內容動態饋給網址:

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

所有附件類型都必須上傳至上層頁面。因此,您在 AttachmentEntry 上設定父項連結。 或嘗試上傳的 WebAttachmentEntry 個物件詳情請參閱「建立子頁面」。

正在上傳附件

以下範例會將 PDF 檔案上傳到使用者內容動態饋給中的第一個 FileCabinetPageEntry。 系統會建立附件,標題為「Getting Started」以及 (選用) 說明和「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"));

網頁附件

網頁附件是一種特殊的附件。基本上,這些檔案是連結至網路上其他檔案的連結 請將其新增至檔案櫃清單。此功能類似於「透過網址新增檔案」Google 協作平台使用者介面中的上傳方法。

注意:您只能在檔案櫃頁面建立網頁附件。無法上傳至其他類型的網頁。

此範例會在使用者內容動態饋給找到的第一個 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() 方法。這會將 HTTP PUT 要求傳送至項目的 edit 連結。

以下是透過以下變更更新 ListPageEntry 的範例:

  • 標題已改為「已更新標題」
  • 網頁的 HTML 內容已更新為「已更新的 HTML 內容」<p><p></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);
}

這個範例會將 HTTP PUT 要求傳送至項目的 edit-media 連結。傳回的 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,請傳送 HTTP GET 要求至項目的內容 src 連結。

這個範例會下載使用者內容動態饋給中找到的第一個 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 值 設定為「owner」僅是讀者或作者。

擷取 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 資訊提供的連結。 舉例來說,下列程式碼片段會擷取 SiteEntry 的 acl 動態饋給:

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 動態饋給總覽」一節 和 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 參考指南

返回頁首