熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Eclipse環境下的OpenSocial開發

2013-11-23 19:15:46  來源: Java核心技術 

   什麼是 OpenSocial

  OpenSocial 是基於開放標准的一組通用的 API用於幫助 WEB 的開發者構建跨多個社交網站的可移植的社交應用程序OpenSocial 提供開發者一套通用的 API基於該通用 API 開發的社交應用程序可以運行在任意支持 OpenSocial 規范的社交網站上

  關於更多的有關 OpenSocial 內容請讀者參見

   Apache Shindig

  Shindig 是 OpenSocial 規范的引用實現其主要的組件包括 :

  Gadget Container JavaScriptOpenSocial Gadget 容器客戶端的 JavaScript 類庫 (gadgetjs)提供例如 UI LayoutSecurity Communication 等相關的功能

  Gadget Rendering Server負責解析 Gadget XML 轉化成浏覽器使用的 HTML/JavaScript/CSS

  OpenSocial Container JavaScript位於客戶端的 OpenSocial 容器也是 JavaScript 類庫提供 OpenSocial 相關的功能例如存取 People Activity AppData 等相關的社交數據

  OpenSocial Data Server提供基於 Restful/RPC 協議的 Services用於存取 People Activity AppData 等相關的社交數據

  圖 是 Shindig 的服務器端架構圖

  圖 Shindig Architecture( 引自 Chris Schalk@GoogleTM)  

  OpenSocial定義及Apache Shindig

  從圖 中可以看到Shindig 基於 Java Servlet Stack 實現GadgetRenderingServlet 負責 Gadget Rendering 而 DataServiceServlet 和 JsonRpcServlet 實現 OpenSocial Data Server 中相對應的 Restful 及其 RPC 服務JsonDbOpensocialService 通過實現 ActivityService PersonService AppDataService 三個接口向 Shindig OpenSocial 容器提供基於 Json 格式的 OpenSocial 數據客戶端的 Gadgets 可以使用標准的 OpenSocial API 訪問到這些數據

  關於更多的有關 Apache Shindig 內容請讀者參見


   Eclipse 環境下編譯 / 調試 Shindig

  我們通過以下的步驟來完成

   安裝 Maven plugin

  Maven 是一個基於 Java 的代碼構建和依賴管理工具Apache Shindig 的源代碼是通過 Maven 來管理的所以我們需要安裝 Maven 的 Eclipse 插件讀者可以使用 Eclipse 的 updatesite 機制連接到站點安裝

  使用 Subversion 下載 Shindig 代碼

  在 使用 SVN 客戶端下載到 Shindig 的源代碼

   編譯和調試 Shindig

  首先在 Eclipse IDE 裡通過 File/Import/General/Maven Projects 選項導入我們下載的所有 Shindig 的源代碼導入完成後Shindig 就作為幾個 Maven 工程存在於你當前的 WorkSpace 中

  通過 Run/Debug Configurations/Maven Build 配置編譯 Shindig 參數如圖 所示

  圖 Package Shindig

  Eclipse 環境下編譯 / 調試 Shindig

  如圖 所示E:\svn_repository\opensocialshindig是你的 Shindig 源代碼的根目錄點擊 Debug 這將使用 Maven 來 Build 整個 Shindig 代碼在 Build 成功後我們使用 Jetty 來啟動 Shindig默認情況下Jetty Server 將運行在 端口如圖 所示

  圖 Run Shindig

  Eclipse 環境下編譯 / 調試 Shindig

  如圖 所示我們設置了 Maven 目標使用 Jetty 來啟動 Shindig 而 Base directory 設置為 shindigserver Maven 工程的根目錄點擊 Debug Jetty Server 運行而 Shindig 部署在 Jetty Server 上 在 Shindig 成功啟動後 你就可以使用//localhost:/gadgets/files/samplecontainer/l來訪問 Shindig 提供的 Gadget 的例子


  Shindig 服務器端 SPI 擴展

  Shindig 作為 OpenSocial 規范的引用實現提供了 SPI 的擴展能力允許你把數據適配到 Shindig 容器中去你的這些數據也許存在於諸如 My SQL/Oracle 的關系數據庫或者是以 JSON 格式存儲的靜態文件無論哪種存儲你都可能通過 Shindig SPI 將它們適配到 Shindig 從而使這些數據公布在 OpenSocial 平台上

  圖 Shindig SPI 擴展

  Shindig 服務器端 SPI 擴展

  如圖 所示你的應用需要實現 ActivityService PersonService AppDataService 三個接口利用諸如 JDBC/Hibernate 等機制把數據提供給 Shindig

  接下來本文將通過一個例子實現 PersonService 接口向 Shindig 提供 People/Friends 相關的 OpenSocial 數據

  清單 是 SocialTestJsonPersonService類的實現

  清單 SocialTestJsonPersonService Class




public class SocialTestJsonPersonService implements PersonService {
  private static final String PEOPLE_TABLE = people;
  private static final String FRIEND_LINK_TABLE = friendLinks;
  private JSONObject db;
  private BeanConverter converter;
       ……
  public Future<RestfulCollection<Person>> getPeople(Set<UserId>
             userIdsGroupId groupId CollectionOptions options Set<String> fields
      SecurityToken token) throws ProtocolException {
    List<Person> result = ListsnewArrayList();
    try {
      //Read people data from JSON table
      JSONArray people = dbgetJSONArray(PEOPLE_TABLE);
      Set<String> idSet = getIdSet(userIds groupId token);

      for (int i = ; i < peoplelength(); i++) {
        JSONObject person = peoplegetJSONObject(i);
        if (!ntains(personget(PersonFieldIDtoString()))) {
          continue;
        }
        // Add group support later
        Person personObj = filterFields(person fields Personclass);
        resultadd(personObj);
      }

      if (GroupIdTypeself == groupIdgetType() && resultisEmpty()) {
        throw new ProtocolException(HttpServletResponseSC_BAD_REQUEST
            Person not found);
      }
      int totalSize = resultsize();
      return ImmediateFuturenewInstance(new RestfulCollection<Person>(
          result optionsgetFirst() totalSize optionsgetMax()));
    } catch (JSONException je) {
      throw new ProtocolException(
          HttpServletResponseSC_INTERNAL_SERVER_ERROR je
              getMessage() je);
    }
  }

  public Future<Person> getPerson(UserId id Set<String> fields
      SecurityToken token) throws ProtocolException {
    try {
      //Read people data from JSON table
      JSONArray people = dbgetJSONArray(PEOPLE_TABLE);
      for (int i = ; i < peoplelength(); i++) {
        JSONObject person = peoplegetJSONObject(i);
        if (id != null
            && personget(PersonFieldIDtoString())equals(
                idgetUserId(token))) {
          Person personObj = filterFields(person fields
              Personclass);
          return ImmediateFuturenewInstance(personObj);
        }
      }
      throw new ProtocolException(HttpServletResponseSC_BAD_REQUEST
          Person not found);
    } catch (JSONException je) {
      throw new ProtocolException(
          HttpServletResponseSC_INTERNAL_SERVER_ERROR je
              getMessage() je);
    }
  }
        ……
}

  從清單 可以看到SocialTestJsonPersonService 實現了 PersonService 兩個接口方法 getPeople 及其 getPersongetPeople 根據傳入參數 userIds返回相應於該 ID 列表的用戶列表而 getPerson 根據傳入參數 id返回相應於該 ID 的用戶

  注意Shindig 依賴 Guice 做動態的依賴注入 (dependency Injection)我們需要在 orgapacheshindigsocialsampleSampleModule 裡指示 Guice 把 PersonService 綁定到 SocialTestJsonPersonService 實現如清單 所示

  清單 SampleModule Class




public class SampleModule extends SocialApiGuiceModule {

  @Override
  protected void configure() {
    nfigure();
    
    bind(Stringclass)annotatedWith(Namesnamed(shindigcanonicaljsondb))
        toInstance(sampledata/canonicaldbjson);
    
    bind(Stringclass)annotatedWith(Namesnamed(shindigsocialtestjsondb))
    toInstance(sampledata/socialtestdbjson);
    
    
    bind(ActivityServiceclass)to(JsonDbOpensocialServiceclass);
    bind(AppDataServiceclass)to(JsonDbOpensocialServiceclass);
    //bind(PersonServiceclass)to(JsonDbOpensocialServiceclass);
    bind(PersonServiceclass)to(SocialTestJsonPersonServiceclass);
    
    bind(MessageServiceclass)to(JsonDbOpensocialServiceclass);
    
    bind(OAuthDataStoreclass)to(SampleOAuthDataStoreclass);


    // We do this so that jsecurity realms can get access to the jsondbservice singleton
    requestStaticInjection(SampleRealmclass);
  }
  ……
}

  從清單 還可以看到標記為shindigsocialtestjsondb的字符串綁定到了sampledata/socialtestdbjson socialtestdbjson 是我們示例中的 JSON 數據文件用來保存 People 數據在 SocialTestJsonPersonService 的實現中dbgetJSONArray(PEOPLE_TABLE) 就是從該 JSON 文件獲取所有的 People 數據

  在下一節我們給出客戶端實現來消費 socialtestdbjson 中的 Social 數據


   Gadget/Restful 客戶端實現

   Gadget 實現

  清單 SocialAppTestxml




<?xml version= encoding=UTF?>
<Module>
    <ModulePrefs
            title=Social Application Test
            author_email=>
            <Require feature=osapi />
            <Require feature=dynamicheight />
    </ModulePrefs>
    <Content type=html ><![CDATA[<! Fetching People and Friends >
<div>
  <button onclick=fetchPeople();>Fetch people and friends</button>
  <div>
    <span id=viewer></span>
    <ul id=friends></ul>
  </div>
</div>
<script type=text/javascript>
var allPeople;
function render(data) {
    var viewer = dataviewer;
    allPeople = dataviewerFriendslist;
    
    documentgetElementById(viewer)innerHTML = viewerid;
    documentgetElementById(friends)innerHTML = ;
    for (var i = ; i < allPeoplelength; i++) {
         documentgetElementById(friends)innerHTML += <li> +
                                                  allPeople[i]nameformatted + </li>;
    }
    gadgetswindowadjustHeight();
}

function fetchPeople() {
    var fields = [idagenamegenderprofileUrlthumbnailUrl];
    var batch = osapinewBatch();
    batchadd(viewer osapipeoplegetViewer({sortBy:namefields:fields}));
    batchadd(viewerFriends
              osapipeoplegetViewerFriends({sortBy:namefields:fields}));
    batchadd(viewerData osapiappdataget({keys:[count]}));
    batchadd(viewerFriendData
              osapiappdataget({groupId:@friendskeys:[count]}));
    batchexecute(render);
}

</script>]]></Content>
</Module>

  如清單 所示fetchPeople 使用了 osapi 獲得 OpenSocial 數據並把它們展示在 HTML 頁面上osapi 是一個輕量級的 JavaScript 類庫用於幫助客戶端獲得 OpenSocial 數據顯示該 Gadget 的 HTML 頁面代碼 (l)請讀者詳見文章後面的資源類表在這裡我們就不一一列出

  現在我們可以在 Eclipse IDE 中啟動 Shindig 在你的浏覽器裡輸入地址

  //localhost:/gadgets/files/samplecontainer/l打開 SocialAppTest Gadget點擊Fetch people and friends按鈕SocialAppTest Gadget 向本地 Shindig 請求數據Shindig 從 socialtestdbjson JSON 文件中獲取數據返回給 Gadget 並在浏覽器中顯示如圖 所示

  圖 SocialAppTest Gadget

  Gadget客戶端實現


  RESTful 客戶端實現

  另外我們還可以選擇使用 Java 應用程序通過 REST 協議獲得 OpenSocial 數據如清單 所示

  清單 RESTful Client 實現




public class SocialAppTest {
    private static final String BASE_URI = //localhost:/social/rest/;
    
    private static final String VIEWER_ID = johndoe;

    public static void main(String[] args) {
        OpenSocialClient client = new OpenSocialClient(SocialAppTest);
        clientsetProperty(OpenSocialClientPropertyREST_BASE_URI BASE_URI);
        clientsetProperty(OpenSocialClientPropertyVIEWER_ID VIEWER_ID);
        try {
            OpenSocialPerson viewer = clientfetchPerson(VIEWER_ID);
            Systemoutprintln(Viewer: + viewergetId());
            Collection<OpenSocialPerson> friends = clientfetchFriends(viewergetId());
            for (OpenSocialPerson friend : friends) {
                Systemoutprintln(Friend: + friendgetId());
            }
        } catch (Exception e) {
            eprintStackTrace();
        }
    }
}

  清單 的運行結果和 SocialAppTest Gadget 一樣顯示當前的 Viewer 及其他的朋友

    結束語

  通過本文讀者已經了解了如何使用 Shindig SPI 來將自己的 Social 數據適配到 Shindig 平台也了解了如何構建客戶端的應用來消費這些 Social 數據

  現在我們不妨回頭總結一下整個 OpenSocial 平台的系統結構一般來說OpenSocial 系統應用使用 OpenSocial   Gadget 作為應用前端OpenSocial Gadget 類似於 iGoogle Gadget不過增加了 OpenSocial 數據的訪問能力當然你也可以使用基於 REST/RPC 協議構建的桌面 RCP 應用作為前端而對於 OpenSocial 平台服務器端也有兩個選擇一則如本文所討論的這樣利用成熟開源的與 OpenSocial 規范相兼容的 OpenSocial 容器實現 ( 例如 Shindig)通過 SPI 擴展實現自己的 OpenSocial 容器或者你從頭開始實現 OpenSocial 規范相兼容的 OpenSocial 容器


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26538.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.