程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java開發2.0: 針對Google App Engine的Gaelyk

Java開發2.0: 針對Google App Engine的Gaelyk

編輯:關於JAVA

本 系列 將探討對於如今及未來的 Java™ 開發的發展起決定作用的各 個技術方面。Java 開發 2.0 的前提開發速度將越來越快,這要歸功於開源領域 中的創新以及硬件的商業化。您可以租借其他人的硬件平台來托管自己的應用程 序(主要使用開源庫、工具和框架來裝配),成本只包括獲取和維護自己的基礎 設施。

本系列的第一期 “使用 Google App Engine” 討論 了免費租借 Google 的基礎設施來托管您的 Java 應用程序(不過會犧牲少許靈 活性)的概念。在後續文章中,您了解了 App Engine 和 Amazon 的 EC2 之間的 差異。上個月的文章 “通過 CouchDB 和 Groovy 的 RESTClient 實現 REST” 調查了關系數據庫的潛在替代方案:CouchDB。CouchDB 缺少模式以 及其面向文檔的特性對您來說可能有點新鮮,但您已經目睹了 Google App Engine 實現的另一個無模式數據存儲。

本文又將回過頭來討論 Google App Engine。開源世界已經跳上了 App Engine 列車,針對該平台的應用程序開 發加速架構層出不窮。您將了解 Gaelyk 框架如何利用本系列已經介紹的許多技 術來進一步簡化應用程序的開發。

輕量級是全新的趨勢

雖然 Google 的基礎設施大多是可以免費使用的(當存儲空間和帶寬達到 500MB,每月 頁面訪問量達到大約 5 百萬次時便要收費),但它會在一定程度上犧牲一些靈活 性。Google 的基礎設施支持 Java 技術,但這並不包括所有 的核心 Java 庫和 相關開源庫。App Engine 是一個平台 — 您需要基於它進行開發。但不足 為奇的是,開源創新將幫助克服采用 Google App Engine 過程中的障礙。

Gaelyk 框架就是這種項目的一個典型,其目的是加速輕量級應用程序的 開發,即使用 Groovy 開發的、適當利用模型-視圖-控制器 (MVC) 模式的應用 程序。在 Groovy 的魔力下,Gaelyk 將為 App Engine 的 API 注入一些易用性 因素。此外,您還可以將 Gaelyk 與針對 Eclipse 的 Google App Engine 插件 結合使用。快速開發和部署 Google App Engine 應用程序將變得非常簡單。

“通過 CouchDB 和 Groovy 的 RESTClient 實現 REST” 利用一個停車罰單 系統演示了面向文檔的數據庫的特性。在本文中,我將繼續創建一個支持創建、 更新和刪除停車罰單的 Web 應用程序。Google 持久性架構不是面向文檔的,但 其無模式特性實現了一個更加靈活的模型。因此,Web 將盡可能准確地建立一個 停車罰單模型,這需要獲取:

警官姓名

日期

位置

違規情況

任何相關注釋

我保留位置為一個普通的文本框,因為一些人可以使用各種方式來表示違規發 生的位置 — 比如在 Best Buy 的停車區 或者在 18 號街和 D 大街的拐角處。 實際上,我不會嘗試描述一個特定格式,因為它不一定適合這個域。

首先,您需要安裝針對 Eclipse 的 Google App Engine 插件(參見 “使用 Google App Engine” 了解詳細步驟)。您還需要從項目的網站下載 Gaelyk JAR 文件(參見 參考資料)。記住這個下載的位置,因為您隨後需要將它移動到一個 特定的目錄中。

Gaelyk 框架依賴於 Groovy,因此您還需要最新的 Groovy 發行版:在撰寫本 文時,它是一個簡單的 JAR 文件,即 groovy-all-1.6.5.jar(參見 參考資料) 。最後,您需要通過 Google App Engine 管理面板創建一個應用程序 ID。(如 果願意,您可以重用在 “使用 Google App Engine” 中創建的應用程序 ID)。

接下來,在 Eclipse 中創建一個新的 Google Web Application Project,單 擊 Next 按鈕並填入適當的信息。確保取消選中了 Use Google Web Toolkit 選 項,如圖 1 所示,因為您不需要它:

圖 1. 在 Eclipse 中創建一個 Google Apps Project

單擊 Finish 按鈕,您將建立好代碼基礎。

現在,將 Groovy 和 Gaelyk JAR 復制到新創建項目的 war/WEB-INF/lib 目錄中,如圖 2 所示:

圖 2. Gaelyk 的必需庫

要配置 Gaelyk,您需要為 Google App Engine 提供一些額外的信息, 方法是編輯 WEB-INF/appengine-web.xml 文件。將您的應用程序 ID 添加到此文 件頂部的應用程序部分,並添加一些 XML,如清單 1 所示:

清單 1. 對 App Engine 配置的必要更新

<static-files>
  <exclude path="/WEB-INF/**.groovy" />
 <exclude  path="**.gtpl" />
</static-files>

添加這些 內容將防止 Google App Engine 靜態提供最終在使用 Gaelyk 時會創建的各種文 件。如您所見,Gaelyk 將利用一個模板模型。因此,使用 .gtpl 擴展名的文件 將類似於 JavaServer Pages (JSP) 並且將通過框架而非 App Engine 進行處理 。

接下來,打開 web.xml 文件。該文件也可以在 WEB-INF 目錄中找到。 它是標准的 Web 應用程序配置文件。(您將在初次訪問 App Engine 和 EC2 時 操作此文件。)該文件需要將各種模式映射到特定的 servlet,因此根據清單 2 調整您的文件:

清單 2. 更新後的 web.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<web- app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   version="2.5">
 <servlet>
 <servlet- name>GroovletServlet</servlet-name>
 <servlet- class>groovyx.gaelyk.GaelykServlet</servlet-class>
  </servlet>
 <servlet>
 <servlet- name>TemplateServlet</servlet-name>
 <servlet- class>groovyx.gaelyk.GaelykTemplateServlet</servlet-class>
 </servlet>
 <servlet-mapping>
 <servlet -name>GroovletServlet</servlet-name>
 <url- pattern>*.groovy</url-pattern>
 </servlet- mapping>
 <servlet-mapping>
 <servlet- name>TemplateServlet</servlet-name>
 <url- pattern>*.gtpl</url-pattern>
 </servlet- mapping>
 <welcome-file-list>
 <welcome- file>index.gtpl</welcome-file>
 </welcome-file- list>
</web-app>

注意,web.xml 文件指定 welcome 文件為 index.gtpl;因此,將 Eclipse 插件為您生成的 index.html 文件重命名為 index.gtpl。(如果使用 Windows® 操作系統,則只需選擇文 件並按下 F2。)

安置好適當的庫並正確配置了兩個 XML 文件之後,您可以驗證一切是否運行 正常,這需要編輯 index.gtpl 文件讓它匹配清單 3 的內容:

清單 3. 一個簡單的 GTPL 文件

<html>
  <head><title>A Simple GTPL</title></head>
  <body>
   <b><% print "Hello Gaelyk!".replace(" ", " from ") % ></b>
   <p>
   <ol>
   <% def wrd = "Groovy"
     wrd.each{ letter ->
   %>
   <li><%= letter %></li>
   <% } %>
   </ol>
   </p>
  </body>
</html>

可以看到,Gaelyk 中的 GTPL 文件(或 Gaelyk/Groovy 模板)類似於 JSP: 您可以在 scriptlet 中添加行為(在本例中,添加的行為是 Groovy)。注意, 稍後您也可以使用閉包和引用變量。

保存您的 index.gtpl 文件在 Eclipse 中選擇項目的基本目錄,單擊鼠標右 鍵,選擇 Run As 並選擇包含藍色 G 徽標的 Web Application 選項,如圖 3 所 示:

圖 3. 作為 Google Web 應用程序運行

默認情況下,此啟動程序將在端口 8080 上啟動一個本地 Jetty 實例。如果 要更改端口,請選擇 Run Configurations 選項並通過插件提供的選項面板配置 端口。

運行 Gaelyk Web 應用程序的本地實例之後,打開一個 Web 浏覽器並訪問 http://localhost:8080。index.gtpl 的輸出應如圖 4 所示:

圖 4. Hello world!

非常簡單,不是嗎?

簡單的持久性

罰單系統非常簡單。它提供了一個 Web 表單,可用於創建罰單以及在列表中 查看、刪除和編輯罰單。我首先將通過 Gaelyk 模板創建一個簡單的 HTML 表單 ,並將它命名為 createticket.gtpl。如圖 5 所示,這個表單將嘗試捕獲與各停 車罰單相關的數據:

圖 5. 一個簡單的罰單表單

表單將提交給一個 groovlet;相應地,在項目的 WEB-INF 目錄中創建一個 groovy 文件夾。您的 groovlet 將存放在此處。(您在 “使用 Google App Engine” 中也完成了此操作。創建罰單(create-ticket)表單將提交給一個 createticket.groovy 文件。在新創建的 groovy 目錄中創建此文件。

毫無疑問,您可以在 Gaelyk 中使用 JDO 和 Java Persistence API (JPA) 代碼,但是也可以采用另外一種方法來與底層數據存儲交互:即使用 Google 的 Entity 對象。Gaelyk 團隊已憑借一些 Groovy 魔力簡化了持久對象的操作,從 而增強了 Entity 對象。

在本例中,我希望獲取通過 createticket.gtpl 頁面提交的表單元素,並在 系統中創建一個新罰單。通過使用 Entity 類,我不需要定義一個類似於 POJO 的對象來表示罰單(就像我在 “使用 Google App Engine” 中創建 Triathlon JDO 對象時所做的一樣)。我可以采用 Groovy 的方式建立一個罰單模型,並毫 不費力地保存它。

因此,我可以通過 Gaelyk 的 params 對象(Grails 也以某種形式提供了此 對象)獲取由表單提交的參數,並創建一個 Entity 實例,如清單 4 所示:

清單 4. 創建一個 Entity

def formatter = new SimpleDateFormat("MM/dd/yyyy")
def offensedate = formatter.parse("${params.of_month}/ ${params.of_day}/${params.of_year}")

def ticket = new Entity("ticket")
ticket.officer = params.officer
ticket.license = params.plate
ticket.issuseDate = offensedate
ticket.location = params.location
ticket.notes = params.notes
ticket.offense = params.offense

注意,ticket 變量是 Entity 的一個實例。"ticket" String 表示的就是這 種實體。它可以非常便捷地搜索罰單。接下來,我將自動為與罰單相關的 Entity 實例分配屬性值。現在,ticket.officer 表示通過 Web 頁面表單提交的 officer 參數的值。由於該表單包含三個日期字段,我也使用 SimpleDateFormat 創建一個日期實例,並將該值設置為 issueDate。

至此,我已經創建一個用於表示罰單的對象。現在,我要做的就是使用以下代 碼保存它:

ticket.save()

現在,我已經持久化了一個罰單,我將把用戶定向到一個可查看罰單的頁面。 這也非常簡單。我只需要定向到 view-ticket Groovlet(以便處理):

redirect "viewticket.groovy?id=${ticket.key.id}" 

如您所見,我已經創建了一個名稱為 id 的參數,並將它設置為已保存罰單( 由 Google App Engine 生成)實例的鍵。可見,create-ticket Groovlet 非常 簡明和強大 — 這得益於 Gaelyk。

簡易視圖

在上一個示例中,當我創建了 ticket 實例之後,我繼續將請求重定向到另一 個 Groovlet — 它可以簡化罰單的查看過程。在此 Groovlet 中,我編寫了一個 Google App Engine “read”。傳遞的 id 將用於查找新創建的實例。在本例中 ,我將使用 Google 的 KeyFactory,它用於創建 Google 的 Key 對象的實例。 然後,Key 將用於通過 datastoreService 查找相應的罰單實例,而 Gaelyk 已 將它們添加到框架中的任何 Groovlet 實例中,如清單 5 所示:

清單 5. 查看 Entity

import com.google.appengine.api.datastore.KeyFactory

if (params["id"]) {
  def id = Long.parseLong(params["id"])
  try {
   def key = KeyFactory.createKey("ticket", id)
   def ticket = datastoreService.get(key)

   request.setAttribute "ticket", ticket

   forward "viewticket.gtpl"

   } catch (Throwable t) {
   //forward to some error page...
   }
} else {
  forward "index.gtpl"
}

找到相應的 ticket 之後,罰單將被添加到 HTTP request 對象(它已經出現 在 Groovlet 中),然後將處理轉交給 viewticket.gtpl 頁面。與 Web 應用程 序中的任何其他 JSP 一樣,這個 Web 頁面將顯示與傳入罰單相關的相應屬性。

從清單 6 中可以看出,Gaelyk 支持 includes。也就是說,在您的 .gtpl 文 件中,您可以包括其他文件,就像普通 JSP 文件一樣。同樣,所有 .gtpl 文件 都有一個 HTTP Request 對象的實例可用(通過 request 變量)。

清單 6. 查看 Entity GTPL

<% include "/WEB-INF/includes/header.gtpl" %>

<% def ticket = request.getAttribute("ticket") % >

<div class="info">
  <h2>Parking Ticket</h2>
  </div>

<table>
<tr>
  <th>Issuing Officer</th>
  <th>Vehicle Plate</th>
  <th>Date</th>
  <th>Offense</th>
  <th>Location</th>
  <th>Notes</th>
  </tr>
  <tr>
  <td>${ticket.officer} </td>
  <td>${ticket.license}</td>
  <td>${ticket.issuseDate}</td>
  <td>${ticket.offense}</td>
  <td>${ticket.location}</td>
  <td>${ticket.notes}</td>
  </tr>
  </table>

<% include "/WEB-INF/includes/footer.gtpl" %>

至此,您或許可以發現 Gaelyk 使得在 Google App Engine 上創建輕量級 Web 應用程序輕而易舉。並且,操作 App Engine 的持久庫也變得再簡單不過。 您在操作 Entity 時使用的低級 API 確實需要花一些時間習慣。查詢需要一些思 考(在某些方面類似於使用 CouchDB 執行查詢)。舉例來說,查看已創建罰單的 列表需要一些如清單 7 所示的代碼:

清單 7. 查看一組 Entity

import com.google.appengine.api.datastore.Query
import static  com.google.appengine.api.datastore.FetchOptions.Builder.withLimit
try {
  def query = new Query("ticket")
  query.addSort("issuseDate", Query.SortDirection.DESCENDING)
  def preparedQuery = datastoreService.prepare(query)
  def tickets = preparedQuery.asList( withLimit(10) )

  request.setAttribute "tickets", tickets 
forward "index.gtpl"
} catch (Throwable t) {
  forward "index.gtpl"
}

清單 7 使用了 App Engine 的 Query 對象。如您所見,您可以為查詢添加類 似於排序的特性,甚至還能限制返回結果的方式。不需要使用 SQL,但需要確保 數據已存儲並且可以檢索,只存在少許不同。

如 “使用 Google App Engine” 所述,部署到雲的過程也非常簡單。通過插 件,只需要單擊 Deploy App Engine Project,其余的事情就由 Google 來完成 了。事實上,您可以 下載 本文的代碼來完成此操作。代碼將填入一些間隔,因 此我無法在一篇文章列出所有代碼。舉例來說,我實現了刪除罰單的功能,並且 用戶與罰單之間的交互也稍有增強,因此您可以或多或少感受到 Gaelyk 的效果 。

快速開發更加輕松

受到開源技術支持的雲和無模式數據存儲無疑是未來 Java 開發中的一部分。 兩者的采用門檻都較低;在本文的示例中,硬件和軟件都是免費的。並且,一旦 Google 開始收費,那麼肯定要自力更生 — 每月 5 百萬的點擊率是巨大的流量 。Gaelyk 框架加快了 Web 開發的步伐。Java 開發始終在日臻完善,不是嗎?

原文地址:http://www.ibm.com/developerworks/cn/java/j-javadev2-6/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved