歡迎您光臨本站 註冊首頁

用 Geronimo 和 REST 構建伺服器端 mashup

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  
探索使用 Apache Geronimo、基於 REST 的協議和來自各種來源的數據構建 mashup 應用程序時可以使用的技巧與技術。該 mashup 將組合 Google Maps 和 Twitter tweet 中的數據以在 Twitter 用戶更新其 Twitter 狀態時精確定位他們的位置。

mashup 一詞最初被定義為混合兩種或多種樂曲從而創作出全新音樂作品的技術。在軟體工程中,mashup 指組合數據、UI 組件和流程以創建新 Web 應用程序和站點的技術和模式。

在站點開發人員之間,Mashup 十分流行,因為它可以輕鬆地組合數據與內容。這種特性源於動態的且具有豐富語義的 Web 技術的普遍使用 — 這些技術包括 XML、JavaScript Serialized Object Notation(JSON)、資源描述框架(Resource Description Framework,RDF)、動態 JavaScript 和 Ajax。這些技術和其他技術為開發創造性內容的開發人員提供了無限可能性。

常用縮寫詞
  • Ajax:Asynchronous JavaScript + XML
  • API:應用程序編程介面(Application program interface)
  • CSS:層疊樣式表(Cascading Style Sheet)
  • DOM:文檔對象模型(Document Object Model)
  • HTML:超文本標記語言(Hypertext Markup Language)
  • HTTP:超文本傳輸協議(Hypertext Transfer Protocol)
  • UI:用戶界面(User interface)
  • XML:可擴展標記語言(Extensible Markup Language)
  • XSD:XML 模式文檔(XML Schema Document)

通常,可以通過組合 UI 組件、服務/過程以及數據創建 mashup。Mashable UI 組件包括動態 JavaScript、HTML 代碼片段、RSS 摘要和 Web 服務 API 調用的結果。Mashup 使用數據轉換、動態 JavaScript、DOM 處理及其他技術,混合來自一個或多個站點的鬆散耦合的 UI 組件、過程、或數據。當前的典型 mashup 包括將 Google Maps 中的地圖與位置數據結合,例如犯罪統計數字和給定地區的房地產價格。

本文將討論如何將 Twitter 和 Google Maps 提供的 API 與 Ajax 和 Java™ 語言代碼結合使用,構建可以在 Apache Geronimo 環境中部署和執行的 mashup。

了解 Geronimo

Geronimo 是可用於構建企業服務和應用程序的完全兼容的 Java Platform, Enterprise Edition(Java EE)平台。Geronimo 是圍繞使用反轉控制(Inversion of Control,IoC)技術高度解耦服務和組件的架構設計的。這種高度解耦造就了真正的模塊化且可配置的部署和執行環境。Geronimo 提倡使用 Java Management Extension(JMX)和一個類似的特定於 Geronimo 的 MBean 風格的框架,該框架使 Geronimo 成為功能強大的、可管理的企業平台。

您將使用由輕量級內核引擎組裝和管理的可自定義模塊集創建 Geronimo 運行時環境。內核引擎是 Geronimo 模塊,該模塊是由類、其他模塊和可序列化配置組成的集合。在啟動 Geronimo 運行時實例后,Geronimo 內核將載入、裝配並組織模塊。裝配的模塊將決定 Geronimo 部署和執行環境的功能。Geronimo 運行時實例中的所有服務都被部署為模塊。

Geronimo 模塊在 XML 文檔中稱為部署計劃。最終的 Geronimo 部署計劃包含原始部署計劃、Maven project.properties 文件和 Maven Project Object Model(POM)文件的組合。圖 1 顯示了如何處理這些工件以創建最終部署計劃。


圖 1. 處理 Geronimo 部署計劃


部署計劃的內容是由 XSD 文件控制的。部署計劃將定義模塊 ID、模塊的環境屬性、模塊的依賴關係、模塊提供的服務及模塊的 Geronimo Beans(GBeans)等等。清單 1 演示了一個簡單的 Geronimo 部署計劃。


清單 1. 示例 Geronimo 部署計劃
<?xml version="1.0" encoding="UTF-8"?>  <module xmlns="http://geronimo.apache.org/xml/ns/deployment-1.1">    <environment>      <moduleId>        <groupId>geronimo</groupId>        <artifactId>example</artifactId>        <version>1.0.0</version>        <type>car</type>      </moduleId>        <dependencies>        <dependency>          <groupId>geronimo</groupId>          <artifactId>j2ee-server</artifactId>          <type>car</type>        </dependency>      </dependencies>      <hidden-classes/>      <non-overridable-classes/>    </environment>        <gbean name="ExampleService" class="com.example.myservices.MyServiceGBean">      <attribute name="prop1">12345</attribute>      <attribute name="prop2">This is a value for a property</attribute>    </gbean>  </module>  

在構建過程編譯清單 1 中所示的部署計劃時,將用一個惟一名稱創建配置歸檔(Configuration Archive,CAR)文件。為清單 1 中的配置生成的惟一名稱是 geronimo/example-1.0.0/car。

Geronimo CAR 文件

Geronimo CAR 文件是 Java Archive(JAR)文件,其中包含一系列部署計劃和任何其他額外資源。部署計劃系列包含在 CAR 的 META-INF 目錄下名為 config.ser 的文件中。CAR 文件都是在構建過程中由 Geronimo 的 Maven 封裝插件創建的。

Geronimo 存儲庫

Geronimo 存儲庫 是一張工件註冊表,通常表現為文件系統中的文件夾層次結構。Geronimo 的二進位版本將提供名為 repository 的文件夾,其中包含組成核心 Geronimo 平台的模塊的所有依賴關係。

在 Geronimo 中,工件是任意的組件,例如存儲於 Geronimo 存儲庫中的 Web Archive(WAR)文件、JAR 文件或者 CAR 文件。工件存儲於命令行部署實用程序或 Geronimo 發行版附帶的 Geronimo Web 控制台中。

下載並安裝 Geronimo

下載 Geronimo 平台(請參閱 參考資料),然後將文件解壓縮到名為 GERONIMO_HOME 的目錄中。在安裝了 Geronimo 之後,打開命令行控制台並切換到 GERONIMO_HOME/bin 目錄,然後運行 startup.sh。執行此命令將在一個新控制台窗口中啟動伺服器。在伺服器啟動后,您應當會看到類似圖 2 中所示的屏幕。


圖 2. Geronimo 啟動控制台


在建立 Geronimo 運行時環境時,啟動控制台將顯示裝入和啟動的模塊、連接器和應用程序。您可以使用同樣在 Geronimo 安裝的 GERONIMO_HOME\bin\ 目錄中找到的 shutdown.sh 腳本來停止 Geronimo 運行時。





了解 REST

具象狀態傳輸(Representational State Transfer,REST)是用於訪問和更新網路資源的軟體架構模式和調用樣式。Roy Thomas Fielding 所撰寫的論文(請參閱 參考資料)中定義的 REST 一詞,通常用於描述使用默認的 HTTP 方法集(GET、POST、DELETE 和 PUT)所定義的標準請求和響應通過 HTTP 傳輸數據。

REST 架構樣式強烈建議使用統一資源標識符(URI)來定位和訪問資源的表示 — 稱為資源的具象狀態。使用有限的創建/讀取/更新/刪除(CRUD)動作集,並且除 HTTP 之類標準協議提供的內容之外只需極少的額外開銷,就可以訪問和修改具象狀態。基於 REST 的約定應當保持無狀態,從而使其成為諸如 RSS、RDF、Web Ontology Language(OWL)和 Atom 之類語義數據格式的主要促進者。





了解 Google Maps

Google Maps API 提供了若干種處理地圖或者創建和檢索可以嵌入到 Web 頁面中的地圖的方法。本文旨在討論 Google Maps API 提供的基於給定位置字元串檢索地圖的功能。

Google Maps 的公共介面

Google Maps 提供了使用標準 HTTP 請求就可以訪問的 API。每個 API 請求要求事先取得 API 密鑰。Google Maps API 支持 KML 和 GeoRSS 數據格式的 HTTP 響應。

使用 Google Maps API

要開始使用 Google Maps API,必須先在 Google Code 站點中註冊以獲得 API 密鑰。收到的密鑰將對於單個 Web 域有效。

用 Google Maps 檢索地圖

Google Maps 將公開能夠檢索給定位置的地理編碼轉換的 API。要檢索用戶的位置信息和其他信息,只需使用 http://maps.google.com/maps/geo?q=Salt+Lake+City%2C+UT&output=xml&key={apikey} 發出標準 HTTP GET 請求。必須用 Google 分配給您的 API 密鑰替換 {apikey}。下例顯示了如何通過命令行用 curl 使用 API。

C:\>curl -G http://maps.google.com/maps/geo?q=Salt%20Lake%20City     %2C%20UT%26output=xml%26key=ABQIAAAA7kHuyDenRy7D_     kXwDkUfhBQCabR54RQscLxLTjQlrb8wKm07EBRSANMlyMuVIxp6jUQazrN52Pzp3w  

響應將返回基於 XML 的數據,稱為包含關於給定位置信息的 KML。KML 是由 Open Geospatial Consortium Inc.(OGC)維護的開放標準。下面顯示了鹽湖城的 KML 數據示例。


清單 2. KML 文檔示例
	  <kml xmlns="http://earth.google.com/kml/2.0">    <Response>      <name>Salt Lake City, UT</name>      <Status>        <code>200</code>        <request>geocode</request>      </Status>      <Placemark id="p1">        ...        <Point>          <coordinates>-111.888189,40.771592,0</coordinates>        </Point>      </Placemark>    </Response>  </kml>  

在此清單中,<coordinates> 元素包含分別表示鹽湖城的經度、緯度和海拔的值。





了解 Twitter

Twitter 提供了允許用戶使用標準 HTTP 請求、即時消息和文本消息相互聯繫的服務。Twitter 服務的前提是讓用戶發送短消息,稱為 tweets,用於描述用戶正在做什麼。tweets 將被分發到 Twitter 伺服器並轉發給發送 tweets 的用戶的 “跟隨者(follower)”。

Twitter 的公共介面

Twitter 提供了使用標準 HTTP 請求可以訪問的一組 API。Twitter API 圍繞 REST 架構鬆散構建。每個 Twitter API 目前都支持 XML、JSON、RSS 和 Atom 數據格式的 HTTP 響應。下面的例子通過命令行結合使用 Twitter API 與 curl 來檢索 RSS 格式的 Twitter 公共歷史:C:\>curl -G http://twitter.com/statuses/public_timeline.rss。

其他 API 可用於執行諸如檢索朋友的歷史、發布內容狀態更新、更新配置文件位置和檢索用戶的配置文件數據之類的任務。

檢索 Twitter 用戶的位置

Twitter 將公開能夠檢索用戶配置文件的 location 屬性的 API。要檢索用戶的位置和其他信息,只需使用 http://twitter.com/users/show/{targetUserID}.xml 創建一個標準的 HTTP GET 請求。必須用要檢索其信息的用戶的 Twitter ID 替換 {targetUserID}。下面顯示了通過命令行用 curl 使用此 API 的示例:

C:\>curl -G http://twitter.com/users/show/jhanson583.xml  

響應將返回 XML 格式的數據,其中包含用戶信息,包括在用戶的配置文件中配置的用戶位置。下面顯示了用戶 jhanson583 的 XML 數據示例。


清單 3. Twitter 用戶配置文件的 XML 數據示例
<?xml version="1.0" encoding="UTF-8"?>  <user>    <id>10852552</id>    <name>Jeff Hanson</name>    <screen_name>jhanson583</screen_name>    <location>Salt Lake City, UT</location>     …  </user>  

在這裡,<location> 元素將包含輸入到用戶 jhanson583 的配置文件中的數據。注意,由於可以鍵入任意格式的字元串,因此不能夠保證可以有效地應用於 Google Maps 查詢中。因此,只能檢索用戶配置文件中在 <location> 元素中包含有效位置數據的地圖數據。以上配置文件中所示的位置數據可以有效地應用於 Google Maps 查詢中。

用 Java 代碼檢索 Twitter 用戶的位置

檢索用 Java 語言編寫的用戶配置信息只需發送 HTTP GET 請求並解析響應。清單 4 中的代碼片段提供了發送通用 HTTP GET 請求的 Java 代碼。


清單 4. 用 Java 語言編寫的 HTTP 請求示例
  public static String sendHTTPRequest(String url)      throws Exception    {      String res = null;        try      {        HttpURLConnection con = null;        InputStream inStream = null;        OutputStream outputStream = null;          try        {          con = (HttpURLConnection) new URL(url).openConnection();          con.setDoInput(true);          con.setRequestMethod("GET");          inStream = con.getInputStream();          res = parseHTTPResponse(inStream);        }        finally        {          try          {            inStream.close();            outputStream.close();            con.disconnect();          }          catch (Exception e)          {          }        }      }      catch (IOException e)      {        e.printStackTrace();      }        return res;    }      public static String parseHTTPResponse(InputStream inStream)      throws IOException    {      BufferedReader br = null;      br = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));      StringBuffer buf = new StringBuffer();      String line;      while (null != (line = br.readLine()))      {        buf.append(line).append("\n");      }      return buf.toString();    }  

在此清單中,HttpURLConnection 元素用於發送 GET 請求。請求的響應將以 InputStream 形式被檢索,然後逐行讀取以訪問 XML 數據。使用上面用於發送 HTTP 請求的代碼,您可以向 Twitter API 發出檢索用戶配置文件的調用,如下所示:


清單 5. 檢索用 Java 語言編寫的 Twitter 配置文件數據的 HTTP 請求
public class Twitter  {    private static final String API_URL = "http://twitter.com/users/show/";      public static String getUserLocation(String targetUserID)      throws Exception    {      String response =        HTTP.sendHTTPRequest(API_URL + targetUserID + ".xml", null);      DocumentBuilder docBuilder =         DocumentBuilderFactory.newInstance().newDocumentBuilder();      Document doc =        docBuilder.parse(new InputSource(new StringReader(response)));      if (null != doc)      {        NodeList nodeList = doc.getElementsByTagName("location");        if (null != nodeList && nodeList.getLength() > 0)        {          Node locationNode = nodeList.item(0);          if (null != locationNode)          {            return locationNode.getTextContent();          }        }      }        throw new Exception("Invalid HTTP response content encountered");    }  }  





了解 Ajax

Ajax 包括一系列技術和概念,用於在支持 JavaScript 的瀏覽器與 HTTP 伺服器之間進行交互,不需要直接刷新頁面就可調用伺服器請求。Ajax 還是使用 JavaScript、CSS、DOM 處理等動態更新瀏覽器頁面的技術和概念集。通過瀏覽器頁面檢索伺服器數據以及應用數據而不刷新頁面的功能為創建基於瀏覽器的應用程序提供了方便的環境,其豐富的 UI 體驗可以與桌面應用程序相媲美。

基於 Ajax 的頁面需要使用名為 XMLHttpRequest 對象的 JavaScript 對象。此對象用於同步或非同步地將 HTTP 請求從瀏覽器傳輸到伺服器並且接收來自伺服器的響應。

清單 6 中的代碼片段將在 ajaxPost 方法中創建 XMLHttpRequest 對象的實例。XMLHttpRequest 對象隨後用於在伺服器框架中調用標準的 HTTP POST 方法。在伺服器框架中檢索的數據是通過 XMLHttpRequest 對象的 send 方法控制的,將在其中檢索、解析數據並把數據傳遞給 createMap 方法,從中創建 Google Maps 地圖並應用於頁面。


清單 6. 處理 XMLHttpRequest 請求和響應
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0     Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">  <head>    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>    <title>Google Maps</title>        <script src="http://maps.google.com/maps?file=api&v=2&key=..."      type="text/javascript"></script>      <script type="text/javascript">      //<![CDATA[        if (GBrowserIsCompatible())      {        // =============================================        // createMarker function        // =============================================        function createMarker(point, html)        {          var marker = new GMarker(point);          GEvent.addListener(marker, "click", function()          {            marker.openInfoWindowHtml(html);          });          return marker;        }          // =============================================        // createMap function        // =============================================        function createMap(latitude, longitude, twitterUser)        {          // Display the map, with some controls, and set the initial location          var map = new GMap2(document.getElementById("map"));          map.addControl(new GLargeMapControl());          map.addControl(new GMapTypeControl());          map.setCenter(new GLatLng(latitude, longitude), 8);            // Set up marker            var point = new GLatLng(latitude, longitude);          var marker = createMarker(point, twitterUser)          map.addOverlay(marker);        }                // =============================================        // ajaxPost function        // =============================================        function ajaxPost(apiURL)        {          var twitterUser = document.getMapForm.TwitterUser.value;          var xmlRequest = new XMLHttpRequest();            // The false parameter indicates a synchronous call          //          xmlRequest.open("POST", apiURL + '?TwitterUser=' + twitterUser, false);          xmlRequest.send(twitterUser);          if (xmlRequest.status == 200)          {            if (xmlRequest.responseText)            {              var xmlDoc = xmlRequest.responseXML;                var latitude =                xmlDoc.getElementsByTagName('latitude')[0].firstChild.data;              var longitude =                xmlDoc.getElementsByTagName('longitude')[0].firstChild.data;                createMap(latitude, longitude, twitterUser);            }          }          else          {            alert("ajaxPost failed with status: " + xmlRequest.status);          }        }      }      else      {        // display a warning if the browser was not compatible        alert("Sorry, the Google Maps API is not compatible with this browser");      }        //]]>    </script>  </head>    <body onunload="GUnload()">    <p/>    <form method="POST"      action="javascript:ajaxPost('http://localhost:8080/twoogle/service/getMap')"      name="getMapForm">    Twitter user name: <input type="text" value="" name="TwitterUser"/>    <input type="submit" value="Get Map" name="submit"/>  </form>    <p/>    <div id="map" style="width: 550px; height: 450px"></div>  </body>    </html>  

代碼將使用針對給定 Twitter 用戶檢索的緯度和經度創建 Google Maps 地圖。該地圖隨後將被應用到頁面的 DOM 中,它將成為地圖 <div> 元素的子元素。





使用 REST 和 Ajax 技術處理 Twitter 和 Google Maps 數據

使用檢索 Twitter 用戶位置數據和 Google Maps 的地理編碼數據的功能,您可以構建相關服務以發布 Twitter 數據和 Google Maps 數據,mashup 可以使用並組合這些數據,並通過組合的數據生成聚合的 UI。

本文所示的框架將組合來自服務調用的數據,這些服務調用檢索 Twitter 用戶配置文件的位置數據,以及 Google Maps 中位置數據的經度和緯度數據。隨後將在 mashup 頁面的 JavaScript 中使用 Ajax 技術檢索數據,在該頁面中將把數據動態應用到頁面的 DOM 中,以顯示帶有 Twitter 用戶位置的地圖。在 下載 小節中可以獲得本例中的源項目。

框架的控制流程十分簡單:從 mashup 到伺服器端 Ajax-savvy Java servlet 使用 Ajax 來實現基於同步 REST 的服務調用。服務調用的結構為 http://{host}:{port}/twoogle/service/getMap。該 servlet 將把服務調用分派到 Twitter 和 Google Maps 中以檢索 Twitter 用戶的位置。該用戶位置的經度和緯度將被傳遞迴 mashup 並應用於頁面中以創建地圖。圖 3 中顯示了該框架。


圖 3. Twitter/Google Maps mashup 框架


框架將從 mashup 客戶機中接收基於 Ajax 的 HTTP 請求,然後使用請求中的數據以從 Twitter 和 Google Maps 檢索位置數據。給定 Twitter 用戶的經度和緯度值將以 XML 格式傳遞迴 mashup 客戶機,然後進行解析並應用到 mashup 頁面中。





部署和運行框架

Twitter/Google Maps Ajax 和 REST 框架將公開一個 servlet,接收基於 Ajax 的、REST 結構的 HTTP 請求。請求中的數據將被傳遞給 Twitter 和 Google Maps 服務以檢索給定 Twitter 用戶的位置數據。

要部署框架,需要把框架的編譯類以及靜態 HTML 文件和其他資源封裝到一個文件夾中,結構類似 WAR 文件。然後把下面所示的命令應用到 WAR 文件文件夾中,從而把框架部署到 Geronimo 中。

GERONIMO_HOME\bin>deploy --user system       --password manager deploy --inPlace MYAPPDIR\MYAPPNAME  

確保分別用應用程序的位置及應用程序名稱替換 MYAPPDIR 和 MYAPPNAME。您可以使用下面所示的命令從 Geronimo 中取消部署框架:

GERONIMO_HOME\bin>deploy --user system       --password manager undeploy MYAPPNAME  

同樣,確保用應用程序名稱替換 MYAPPNAME。





測試框架

在成功地部署應用程序后,請在 Web 瀏覽器中鍵入以下 URL:http://host:port/twoogle。當出現頁面后,在頁面頂部的框中鍵入 Twitter 用戶名,然後單擊 Get Map。如果用戶的配置文件包含有效的 <location> 元素,則 Google Maps 地圖將顯示在頁面中。

結束語

Apache Geronimo 是可用於構建企業服務和應用程序的 Java EE 平台。Geronimo 是圍繞解耦的服務和組件設計的,可實現一種真正模塊化的、可管理且可配置的部署和執行環境。在站點開發人員之間,Mashup 十分流行,因為它能提供更多可能性並且可以輕鬆地組合數據與內容。這種特性源於動態的且具有豐富語義的 Web 技術的普遍使用 — 這些技術包括 XML、JSON、RDF、動態 JavaScript 和 Ajax。

本文討論了如何組合 REST 樣式的服務調用與 Java 框架中基於 Ajax 的客戶機和伺服器以檢索給定 Twitter 用戶的位置數據。位置數據隨後用於從 Google Maps 中檢索經度和緯度數據,然後使用客戶端 Ajax 技術應用這些數據以創建動態應用到 mashup 頁面中的 Google Maps 地圖。

您現在的任務是下載最新版本的 Geronimo,熟悉 Twitter 的 API 和 Google Maps API,並且熟悉 mashup 的一般概念。使用 REST 和 Ajax 提供的簡化的 Web 應用程序編程模型,您現在可以開始使用功能強大的 Geronimo、Twitter 和 Google Maps 來構建健壯且高度靈活的 mashup。(責任編輯:A6)



[火星人 ] 用 Geronimo 和 REST 構建伺服器端 mashup已經有635次圍觀

http://coctec.com/docs/linux/show-post-69082.html