精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Google App Engine帶來(lái)的Java開(kāi)發(fā)2.0實(shí)現(xiàn)

開(kāi)發(fā) 開(kāi)發(fā)工具 后端
本文介紹了Google App Engine可能對(duì)Java開(kāi)發(fā)帶來(lái)的變革:Java開(kāi)發(fā)2.0概念的引入。通過(guò)利用開(kāi)源工具、框架甚至是解決方案,企業(yè)可以快速地組裝應(yīng)用程序,Java現(xiàn)在正是如此。

Java開(kāi)發(fā)2.0?聽(tīng)起來(lái)是個(gè)挺新穎,但也挺老調(diào)長(zhǎng)談的概念。隨著云計(jì)算的興起,而Google App Engine又提供了Java支持,IBMDW的Andrew Glover在本文中將介紹這個(gè)Java開(kāi)發(fā)2.0是怎么一回事,以及在Google App Engine中又是如何體現(xiàn)的。

Java 世界如同一個(gè)豐富的生態(tài)系統(tǒng),涉及開(kāi)發(fā)人員、事務(wù)以及(最為重要的)應(yīng)用程序等各種角色,其中大部分內(nèi)容在過(guò)去十年里已經(jīng)發(fā)展成熟。全球 Java 社區(qū)在 Java 平臺(tái)上投入了巨大的金錢(qián)、時(shí)間和腦力勞動(dòng),這些貢獻(xiàn)造就了一個(gè)包含成功的開(kāi)源商業(yè)工具、框架以及解決方案的巨大寶庫(kù)。

在 Java 平臺(tái)方面的各種投入使 Java 開(kāi)發(fā)的方式產(chǎn)生了微妙的變化。兩個(gè)重要的趨勢(shì)正在快速改變 Java 開(kāi)發(fā)的特征:

  1. 充分地利用開(kāi)源工具和框架自上而下 構(gòu)建應(yīng)用程序
  2. 租用(或外借)各種應(yīng)用程序基礎(chǔ)設(shè)施來(lái)管理軟件生命周期,包括運(yùn)行應(yīng)用程序本身

我所指的 Java開(kāi)發(fā)2.0 的任何一個(gè)方面都不是新的或革命性的改變,僅僅是實(shí)現(xiàn)技術(shù)已經(jīng)成熟到可以快速、便宜地組裝更好的應(yīng)用程序,這在 Java 技術(shù)的歷史上是從未有過(guò)的 — 這是全世界都希望實(shí)現(xiàn)的主要業(yè)務(wù)需求之一。

本文開(kāi)啟了一個(gè)嶄新的系列,將深入討論 Java開(kāi)發(fā)2.0。您將了解以下內(nèi)容:使用 Amazon EC2 構(gòu)建和部署 Web 應(yīng)用程序、使用 Google 的 App Engine、利用 CouchDB(被稱(chēng)為 Web 的數(shù)據(jù)庫(kù)),以及在短期內(nèi)以目前為止最低的成本組裝、測(cè)試和部署應(yīng)用程序的工具和技術(shù)。

第一站:Google App Engine for Java。我將通過(guò)常用的 “Hello World” 方法來(lái)介紹這個(gè)平臺(tái),然后展示如何使用 Groovy、Java Data Objects (JDO) 和 Eclipse plug-in for Google App Engine 來(lái)創(chuàng)建一個(gè)有效的 Web 應(yīng)用程序。但是,在此之前,讓我們先快速了解一下 Java開(kāi)發(fā)2.0 的商業(yè)價(jià)值。

速度快成本低

快速和便宜以前很少會(huì)和 Java 開(kāi)發(fā)聯(lián)系在一起。事實(shí)上,它們常常讓人聯(lián)想到不太嚴(yán)肅的軟件開(kāi)發(fā) — 只有有限資源的小型企業(yè)進(jìn)行的開(kāi)發(fā)。然而,事實(shí)的真相就是,IT 對(duì)于許多公司(不論大公司還是小公司)都是一個(gè)成本中心,這促使企業(yè)在最大程度獲取價(jià)值的同時(shí)降低 IT 成本。

這就是 Java 開(kāi)發(fā) 2.0 發(fā)揮作用的舞臺(tái)。通過(guò)利用開(kāi)源工具、框架甚至是解決方案,企業(yè)可以快速地組裝應(yīng)用程序,因?yàn)槠髽I(yè)自身不需要編寫(xiě)大量代碼。當(dāng)我在十多年前第一次開(kāi)始使用 Java 技術(shù)進(jìn)行開(kāi)發(fā)時(shí),可供開(kāi)發(fā)人員選擇的工具和框架非常有限。并且這些有限的工具還不是免費(fèi)的。您必須購(gòu)買(mǎi)一個(gè) IDE、一個(gè)數(shù)據(jù)庫(kù)、一個(gè)對(duì)象-關(guān)系映射(ORM)框架(最糟的是,可能必須購(gòu)買(mǎi)一個(gè)驅(qū)動(dòng)程序才能與數(shù)據(jù)庫(kù)通信),當(dāng)然,還需要購(gòu)買(mǎi)在其上部署應(yīng)用程序的機(jī)器。那么現(xiàn)在呢?我剛剛列出的所有(以及更多)內(nèi)容都可以免費(fèi)獲得,并且具有很棒的品質(zhì)。

此外,通過(guò)借用基礎(chǔ)設(shè)施(比如 Amazon EC2 或 Google App Engine 提供的基礎(chǔ)設(shè)施),您可以以非常低的成本部署應(yīng)用程序(您以前需要購(gòu)買(mǎi)所需的基礎(chǔ)設(shè)施)。

構(gòu)建、購(gòu)買(mǎi)還是借用:這是個(gè)新問(wèn)題

許多企業(yè)為運(yùn)行應(yīng)用程序,比如數(shù)據(jù)庫(kù)、應(yīng)用服務(wù)器、變更管理系統(tǒng)和缺陷跟蹤工具,準(zhǔn)備了一個(gè)硬件清單。但是,在現(xiàn)在這個(gè)時(shí)代,這個(gè)清單完全可以扔掉,取而代之的是在其他人的基礎(chǔ)設(shè)施上以運(yùn)行服務(wù)的形式使用相同的軟件包。

團(tuán)隊(duì)用來(lái)管理開(kāi)發(fā)流程的全部應(yīng)用程序堆棧都可以外借 — 也就是說(shuō),花費(fèi)少量的費(fèi)用租用 — 這樣公司就不需要再購(gòu)買(mǎi)運(yùn)行應(yīng)用程序所需的硬件。例如,不需要購(gòu)買(mǎi)機(jī)器來(lái)運(yùn)行變更管理系統(tǒng)(比如 Subversion 或 Git,兩者都是開(kāi)源的免費(fèi)產(chǎn)品),團(tuán)隊(duì)可以使用 GitHub 之類(lèi)的共享變更管理服務(wù)。出租 GitHub 的企業(yè)引入了硬件資產(chǎn)成本,因此需要向使用 Git 的其他組織收取少量費(fèi)用(通常為每用戶(hù)每月收取)。從其他提供商以服務(wù)形式租用軟件的原理可以應(yīng)用于缺陷跟蹤、測(cè)試用例管理和需求管理(比如,通過(guò) Hosted JIRA 或 Pivotal Tracker)。

相同的原理可以應(yīng)用于運(yùn)行其他軟件平臺(tái)的底層硬件資產(chǎn)(通常為定制的)。企業(yè)可以放棄針對(duì)特定 Web 應(yīng)用程序的底層硬件,而傾向于在由 Amazon、Google 或該領(lǐng)域的其他競(jìng)爭(zhēng)者提供的硬件上運(yùn)行應(yīng)用程序。這些企業(yè)提供了以不同程度租用 硬件的能力,這足以托管應(yīng)用程序。并且,這些公司還可以管理可伸縮性、備份甚至安全性。想一下:Amazon 和 Google 許久之前就解決了這些(以及更多)問(wèn)題,現(xiàn)在它們更加擅長(zhǎng)處理并創(chuàng)新高效運(yùn)行軟件平臺(tái)的方面(這是真的,面對(duì)事實(shí)吧)。

例如,通過(guò)使用 Google 的 App Engine,一家 IT 公司就可以降低購(gòu)買(mǎi)基礎(chǔ)設(shè)施以運(yùn)行所需應(yīng)用程序的總體成本。并且可以更加快速地部署這些應(yīng)用程序,因?yàn)橐呀?jīng)考慮并提出了各種與應(yīng)用程序部署和管理有關(guān)的交叉問(wèn)題(并且很可能以一種完美的方式)。

快速 和便宜 不再意味著劣質(zhì)。相反,Java 開(kāi)發(fā) 2.0 是一種戰(zhàn)略性方法,已經(jīng)設(shè)想了一個(gè)以質(zhì)量為重點(diǎn)的可靠流程。

#p#

使用 Google App Engine 減輕負(fù)擔(dān)

Google App Engine 是一個(gè)可以在 Google 的昂貴基礎(chǔ)設(shè)施上構(gòu)建和部署 Java(和 Python)Web 應(yīng)用程序的真正平臺(tái)。無(wú)需任何許可費(fèi)用(當(dāng)然,除非您選擇在基礎(chǔ)設(shè)施上使用的軟件庫(kù)要求擁有一個(gè)許可)、無(wú)需為帶寬或存儲(chǔ)空間支付前期成本。App Engine 基礎(chǔ)設(shè)施在最初是完全免費(fèi)的,直到您達(dá)到了一個(gè)使用閾值 — 500MB 的存儲(chǔ)空間,引述 Google 的話,“為每個(gè)月大約 500 萬(wàn)的頁(yè)面瀏覽提供足夠的 CPU 和帶寬”。可以這樣說(shuō),一旦您達(dá)到了 Google 開(kāi)始收費(fèi)的那個(gè)點(diǎn),您的 Web 應(yīng)用程序已經(jīng)很明顯地產(chǎn)生了巨大的通信量(以及利益)。

啟動(dòng)并運(yùn)行 App Engine 再簡(jiǎn)單不過(guò)了。Google 甚至提供了一個(gè) Eclipse 插件,可以為您處理幾乎任何事情。并且該插件包含 “Hello World” servlet 應(yīng)用程序的基本組件,該應(yīng)用程序可以幫助您開(kāi)始了解此平臺(tái)。在其最近一篇 developerWorks 文章(“Google App Engine for Java:第 1 部分:運(yùn)轉(zhuǎn)起來(lái)!” 中,Rick Hightower 向您介紹了部署 Hello World 應(yīng)用程序(包含屏幕快照)的整個(gè)過(guò)程。如果您還沒(méi)有閱讀 Rick 的文章,那么可以遵循下面的步驟:

  1. 創(chuàng)建一個(gè) Google App Engine 帳戶(hù)(是免費(fèi)的),方法是在 http://code.google.com/appengine/ 中單擊 Getting Started 下的 Sign up 鏈接。
  2. http://code.google.com/appengine/downloads.html 下載 Google App Engine plug-in for Eclipse 并安裝它。
  3. 在 Eclipse 中通過(guò)單擊 New Web Application Project 按鈕創(chuàng)建一個(gè)新項(xiàng)目;在顯示的對(duì)話框中,不要勾選 Use Google Web Toolkit 選項(xiàng)。命名項(xiàng)目和您感興趣的相應(yīng)的包。
  4. 在層次結(jié)構(gòu)中選擇項(xiàng)目并單擊 Deploy App Engine Project 按鈕。
  5. 輸入憑證(在步驟 1 中創(chuàng)建 App Engine 帳戶(hù)時(shí)使用的內(nèi)容)。
  6. 將本地項(xiàng)目與在最初創(chuàng)建 App Engine 帳戶(hù)時(shí)生成的應(yīng)用程序 ID 關(guān)聯(lián)起來(lái)。(您最多可擁有 10 個(gè) ID)。
  7. 單擊 Deploy 按鈕。將看到 Eclipse 控制臺(tái)中閃過(guò)大量文本(插件在后臺(tái)執(zhí)行大量工作,包括增強(qiáng)那些利用 Google 的出色的數(shù)據(jù)存儲(chǔ)服務(wù)所需的類(lèi))。當(dāng)屏幕穩(wěn)定后(并且一切工作正常),您應(yīng)當(dāng)會(huì)看到一條 “Deployment completed successfully” 消息。
  8. 訪問(wèn)在 Google 上的 App Engine 帳戶(hù)頁(yè)面并在 Google 指示板上找到 Versions 鏈接。您將看到自己的已部署的版本及對(duì)應(yīng)的 URL。單擊 URL,然后單擊通向生成的 servlet 的鏈接,您會(huì)看到單調(diào)但令人欣慰的 “Hello, world” 純文本。

使用 Groovlets 編寫(xiě)更少的代碼

您已經(jīng)成功部署了您的第一個(gè) Google App Engine 應(yīng)用程序,并且沒(méi)有編寫(xiě)一行代碼。事實(shí)上,如果計(jì)劃利用 App Engine,您總是要編寫(xiě)一些代碼的 — 但要記住,您可以重用已有的大量代碼來(lái)更加輕松地 完成工作。這些可重用代碼可能是 Google 提供的一些服務(wù)(比如其數(shù)據(jù)存儲(chǔ)或 Google 帳戶(hù)服務(wù))或被移植到 Google 基礎(chǔ)設(shè)施上的開(kāi)源庫(kù)。重用其他人的代碼意味著您常常只需編寫(xiě)更少的代碼 — 而更少的代碼意味著更少的缺陷。

我最喜歡的開(kāi)源庫(kù)(以及平臺(tái))之一就是 Groovy,它總是可以生成更少的代碼行來(lái)創(chuàng)建有效的應(yīng)用程序。Groovy 團(tuán)隊(duì)最近發(fā)布了可以使用 App Engine 的平臺(tái)版本,使您能夠利用 Groovlets 而不是 servlets 來(lái)在短期內(nèi)創(chuàng)建一個(gè)有效的應(yīng)用程序。Groovlets 是一些在行為上類(lèi)似 servlets 的簡(jiǎn)單 Groovy 腳本。由于您已經(jīng)實(shí)現(xiàn)了一個(gè)可以輸出 “Hello, world” 的 servlet,因此我將展示使用 Groovlet 完成同樣的事情是多么地簡(jiǎn)單(您將看到 Groovy 可以減少多少代碼)。

使用 Eclipse 插件在 App Engine 上部署 Groovlet 只需要很簡(jiǎn)單的一些步驟:

  1. http://groovy.codehaus.org/Download 下載 Groovy 的最新模板(撰寫(xiě)本文時(shí)為 1.6.3 版本)。
  2. 找到 groovy-all-1.6.3.jar 并將它放到您的 App Engine 項(xiàng)目的 war/WEB-INF/lib 目錄中。順便說(shuō)一句,在這個(gè)目錄中,您可以放置應(yīng)用程序所需的任何庫(kù)(我將在稍后給出一些注意事項(xiàng))。
  3. 將清單 1 中的內(nèi)容(將 Groovlets 映射到指定的請(qǐng)求)添加到 war/WEB-INF 目錄中的 web.xml 文件:

    清單 1. 更新 web.xml 文件以支持 Groovlets
    						
    < servlet>
     < servlet-name>GroovyServlet< /servlet-name>
     < servlet-class>groovy.servlet.GroovyServlet< /servlet-class>
    < /servlet>
    < servlet-mapping>
     < servlet-name>GroovyServlet< /servlet-name>
     < url-pattern>*.groovy< /url-pattern>
    < /servlet-mapping>
    
  4. 將 groovy 目錄添加到 WEB-INF 目錄;這是保存 Groovlets 的位置。在 groovy 目錄中,創(chuàng)建一個(gè)名為 helloworld.groovy 的新文件。在這個(gè)新文件中,輸入 println "Hello, Groovy baby!"
  5. 更新應(yīng)用程序的版本(假設(shè) 1-1)并重新部署。通過(guò) Google 指示板找到相應(yīng)的 URL,然后在瀏覽器中打開(kāi) /helloworld.groovy,會(huì)看到 Groovy 在 Google 的基礎(chǔ)設(shè)施上輸出了一條 hip 消息。

非常簡(jiǎn)單,不是嗎?您只需要添加 Groovy JAR、更新 web.xml 文件、創(chuàng)建一個(gè)新的 groovy 目錄、編寫(xiě)一個(gè) Groovlet 然后部署它。您是否還注意到 Groovlet 如何只使用一行代碼 完成與默認(rèn) servlet 插件的工作?您希望編寫(xiě)并維護(hù)哪一個(gè):一個(gè)龐大的類(lèi)或是具有相同行為的很小的類(lèi)?

Groovy + Java = 快速構(gòu)建有效的應(yīng)用程序

現(xiàn)在,我將展示如何結(jié)合使用 Groovy 和 Google 的 App Engine 快速創(chuàng)建一個(gè)有效的應(yīng)用程序。我將使用一個(gè)簡(jiǎn)單的 HTTP 頁(yè)面、一個(gè) Groovlet 以及一個(gè)增強(qiáng)了 JDO 的 Java 類(lèi)來(lái)持久化事件(在本例中為 triathlon)。我將在這里保持簡(jiǎn)單性,但是您將會(huì)看到這個(gè)應(yīng)用程序可以不斷演變來(lái)包括其他特性,并且在本系列后續(xù)文章中,您將實(shí)現(xiàn)這些特性(當(dāng)然,使用不同的基礎(chǔ)設(shè)施和技術(shù))。

快速 JDO

Google App Engine 提供了使用 JDO 持久化數(shù)據(jù)的能力,JDO 是一個(gè) Java 持久化標(biāo)準(zhǔn)。對(duì)于大部分 Java 開(kāi)發(fā)人員來(lái)說(shuō),持久化數(shù)據(jù)常常意味著將信息保存到一個(gè)關(guān)系數(shù)據(jù)庫(kù)中;然而,對(duì)于 Google 來(lái)講,底層存儲(chǔ)機(jī)制就是它的 Big Table,而后者并不是關(guān)系型的。也就是說(shuō),這一點(diǎn)無(wú)關(guān)緊要:Google 如何持久化特定屬性的細(xì)節(jié)在很大程度上已經(jīng)被隱藏。可以這樣說(shuō),您可以使用普通的 Java 對(duì)象(或 Groovy 對(duì)象,就本文而言)來(lái)構(gòu)建一個(gè)應(yīng)用程序,這個(gè)應(yīng)用程序可以像任何其他應(yīng)用程序那樣存儲(chǔ)信息。這就是 Google 的方法,您必須使用 JDO。(Hibernate 無(wú)疑是面向 Java 的最流行的 ORM 框架,但它并不能用于 App Engine)。

JDO 非常簡(jiǎn)單。您將創(chuàng)建 POJO — 老式普通 Java 對(duì)象(可以和其他 Java 對(duì)象建立聯(lián)系),您通過(guò)類(lèi)級(jí)別的 @PersistenceCapable 注釋將其聲明為具有持久能力。通過(guò) @Persistent 注釋指定要進(jìn)行持久化的對(duì)象的屬性。例如,我希望存儲(chǔ) triathlon 事件(目前而言,我將關(guān)注事件而不是與 triathlon 有關(guān)的各種結(jié)果)— 就是說(shuō),事件擁有一個(gè)名稱(chēng)(triathlon 的名稱(chēng)),可能還有一個(gè)描述(triathlon 的類(lèi)型)和一個(gè)日期。目前為止,我的 JDO 看上去類(lèi)似清單 2:

清單 2. 一個(gè)簡(jiǎn)單的 triathlon 事件 JDO
				
import java.util.Date;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.IdentityType;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Triathlon {

 @Persistent
 private Date date;

 @Persistent
 private String name;

 @Persistent
 private String description;

}

無(wú)論使用哪一種底層機(jī)制(即關(guān)系型或 Google 的 Big Table),數(shù)據(jù)持久性始終需要涉及鍵(key)的概念:一種為了避免數(shù)據(jù)崩潰而確保數(shù)據(jù)的不同方面具有惟一性的方法。例如,對(duì)于 triathlon,它的鍵可以是 triathlon 的名稱(chēng)。如果兩個(gè) triathlon 擁有相同的名稱(chēng),那么可以將名稱(chēng)和日期組合起來(lái)作為鍵。不管您使用何種方式通過(guò) Google App Engine 和 JDO 表示鍵,必須通過(guò) @PrimaryKey 注釋在 JDO 對(duì)象中指定一個(gè)鍵。您還可以為鍵的生成方式選擇一些策略 — 由您或 Google 生成。我將使用 Google 生成并保持簡(jiǎn)單性:我的 triathlon 對(duì)象的鍵被表示為一個(gè)普通的 Java Long 對(duì)象,并且我將通過(guò)指定一個(gè)值策略 來(lái)讓 Google 確定實(shí)際的值。清單 3 添加了一個(gè)主鍵:

清單 3. 為 triathlon JDO 添加一個(gè)主鍵
				
import java.util.Date;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.annotations.IdentityType;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Triathlon {
 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 private Long id;

 @Persistent
 private Date date;

 @Persistent
 private String name;

 @Persistent
 private String description;

 public Triathlon(Date date, String name, String description) {
  super();
  this.date = date;
  this.name = name;
  this.description = description;
 }

 //...setters and getters left out

 public String toString() {
  return ReflectionToStringBuilder.toString(this);
 }

 public int hashCode() {
  return HashCodeBuilder.reflectionHashCode(this);
 }

 public boolean equals(Object obj) {
  return EqualsBuilder.reflectionEquals(this, obj);
 }
}

如清單 3 所示,我的 triathlon JDO 擁有一個(gè)由 Google 基礎(chǔ)設(shè)施管理的鍵,并且添加了一些標(biāo)準(zhǔn)的方法(toStringhashCodeequals),為調(diào)試、登錄以及適當(dāng)?shù)墓δ芴峁┝藰O大的幫助。我并沒(méi)有親自編寫(xiě)這些內(nèi)容,相反,我使用了 Apache commons-lang 庫(kù)。我還添加了一個(gè)構(gòu)造函數(shù),與調(diào)用大量 setter 方法相比,這個(gè)構(gòu)造函數(shù)可以更加輕松地創(chuàng)建完全初始化的對(duì)象。

我有意維持了 JDO 的簡(jiǎn)單性,但是正如您所見(jiàn),并沒(méi)有包含多少內(nèi)容(就是說(shuō),為了保持簡(jiǎn)單性,我去掉了所有的關(guān)系并忽略了 getter 和 setter 方法)。您只需對(duì)域進(jìn)行建模并隨后使用一些注釋來(lái)修飾模型,然后剩下的工作就由 Google 來(lái)完成。

將對(duì)象定義為具有持久性后,還剩下最后一個(gè)步驟。要與底層的數(shù)據(jù)存儲(chǔ)交互,需要使用 PersistenceManager,這是一個(gè) JDO 標(biāo)準(zhǔn)類(lèi),顧名思義,它的作用就是在一個(gè)底層數(shù)據(jù)存儲(chǔ)中保存、更新、檢索和刪除對(duì)象(非常類(lèi)似于 Hibernate 的 Session 對(duì)象)。這個(gè)類(lèi)通過(guò)一個(gè)工廠(PersistenceManagerFactory)創(chuàng)建,這個(gè)工廠非常復(fù)雜;因此,Google 建議創(chuàng)建一個(gè)獨(dú)立的對(duì)象來(lái)管理工廠的單個(gè)實(shí)例(后者在您需要時(shí)返回一個(gè)合適的 PersistenceManager)。相應(yīng)地,我可以定義一個(gè)簡(jiǎn)單的獨(dú)立對(duì)象來(lái)返回 PersistenceManager 的實(shí)例,如清單 4 所示:

清單 4. 返回 PersistenceManager 實(shí)例的簡(jiǎn)單獨(dú)立對(duì)象
				
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

public class PersistenceMgr {

 private static final PersistenceManagerFactory instance =
   JDOHelper.getPersistenceManagerFactory("transactions-optional");

 private PersistenceMgr() {}

 public static PersistenceManager manufacture() {
  return instance.getPersistenceManager();
 }
}

可以看到,我的 PersistenceMgr 非常的簡(jiǎn)單。manufacture 方法從 PersistenceManagerFactory 的單個(gè)實(shí)例返回一個(gè) PersistenceManager 實(shí)例。您還會(huì)注意到,清單 4 中沒(méi)有出現(xiàn)任何特定于 Google 的代碼或任何其他利用 JDO 的代碼 — 所有引用都是指向標(biāo)準(zhǔn) JDO 類(lèi)和接口的。

新添加的兩個(gè) Java 對(duì)象位于我的項(xiàng)目的 src 目錄中,并且我將 commons-lang 庫(kù)添加到了 war/WEB-INF/lib 目錄中。

利用定義好的簡(jiǎn)單 triathlon JDO POJO 和方便的 PersistenceMgr 對(duì)象,我已經(jīng)有了很好的起點(diǎn)。我所需要的就是能夠捕獲 triathlon 信息。

#p#

通過(guò) Web 接口捕獲數(shù)據(jù)

大多數(shù) Web 應(yīng)用程序都遵循相同的模式:通過(guò) HTML 表單捕捉信息,然后將它們提交到服務(wù)器端資源以進(jìn)行處理。當(dāng)然,這一過(guò)程中還混合了許多其他技術(shù),但是不管底層技術(shù)或基礎(chǔ)設(shè)施如何,模式始終保持不變。Google App Engine 也是如此 — 我已經(jīng)編碼了服務(wù)器端資源來(lái)處理保存的 triathlon 數(shù)據(jù)。剩下的工作就是捕捉信息 — 表單 — 以及將服務(wù)器端與表單連接起來(lái)。按 Model-View-Controller (MVC) 的話說(shuō),我需要一個(gè)控制器(通常為一個(gè) servlet);我將利用 Groovlet 替代,因?yàn)槲蚁M帉?xiě)更少的代碼。

我的 HTML 表單非常簡(jiǎn)單:我所需做的就是創(chuàng)建一個(gè) HTML 頁(yè)面,利用某些簡(jiǎn)單的 Cascading Style Sheets (CSS) 代碼來(lái)創(chuàng)建表單,如圖 1 所示,看上去更接近 Web 2.0,而不是 1998 年出現(xiàn)的 HTML 頁(yè)面:

圖 1. 一個(gè)簡(jiǎn)單的 HTML 表單

一個(gè)簡(jiǎn)單的 HTML 表單

可以從圖 1 中看到,表單捕捉到一個(gè)名稱(chēng)、描述和一個(gè)日期。然而,日期并不簡(jiǎn)單 — 它實(shí)際上是一個(gè)日期的三個(gè)屬性。

快速 Groovlet

Groovlets 使得編寫(xiě)控制器變得非常簡(jiǎn)單:它們需要更少的代碼并自動(dòng)提供了所需的對(duì)象。在 Groovlet 中,您分別通過(guò) requestresponse 對(duì)象隱式地訪問(wèn) HTML 請(qǐng)求和響應(yīng)。在我的 Groovlet 中,我可以通過(guò) request.getParameter("name") 調(diào)用獲得提交的 HTML 表單的所有屬性,如清單 5 所示:

清單 5. Groovlets 的實(shí)際操作
				
def triname = request.getParameter("tri_name")
def tridesc = request.getParameter("tri_description")
def month = request.getParameter("tri_month")
def day = request.getParameter("tri_day")
def year = request.getParameter("tri_year")

前面編寫(xiě)的 JDO 使用了一個(gè) Java Date 對(duì)象;然而,在清單 5 中,我處理了 Date 的三個(gè)不同屬性。因此我需要一個(gè) DateFormat 對(duì)象來(lái)將 monthdayyear 三者的組合轉(zhuǎn)換為一個(gè)普通的 Java Date,如清單 6 所示:

清單 6. 數(shù)據(jù)格式化
				
def formatter = new SimpleDateFormat("MM/dd/yyyy")
def tridate = formatter.parse("${month}/${day}/${year}")

最后,從已提交 HTML 表單獲得所有參數(shù)后,我可以使用清單 7 的代碼,通過(guò)我的 JDO 和清單4的 PersistenceMgr 對(duì)象將它們持久化到 Google 的基礎(chǔ)設(shè)施中:

清單 7. 使用 JDO 輕松實(shí)現(xiàn)持久化
				
def triathlon = new Triathlon(tridate, triname, tridesc)
def mgr = PersistenceMgr.manufacture()

try {
 mgr.makePersistent(triathlon)
} finally {
 mgr.close()
}

就是這么簡(jiǎn)單!當(dāng)然,隨著更多的頁(yè)面加入到我的簡(jiǎn)單應(yīng)用程序中(比如捕捉特定 triathlon 的結(jié)果),我可能需要轉(zhuǎn)發(fā)或重定向到另一個(gè)表單,這將捕捉額外的信息,與向?qū)诸?lèi)似。不管怎樣,通過(guò)一些簡(jiǎn)短的代碼片段,我快速組合了一個(gè)簡(jiǎn)單的 Web 應(yīng)用程序,它可以通過(guò) JDO(使用普通 Java 編碼)和一個(gè) Groovlet(當(dāng)然,使用 Groovy 編碼)將數(shù)據(jù)持久化到 Google 的基礎(chǔ)設(shè)施中。部署應(yīng)用程序非常簡(jiǎn)單,只需在 appengine-web.xml 文件中指定一個(gè)版本并單擊 Deploy 按鈕。

但是,這個(gè)用于捕捉 triathlon 事件的只包含一個(gè)表單的 Web 應(yīng)用程序并沒(méi)有試圖實(shí)現(xiàn)全部的功能,所以說(shuō),我僅僅是將應(yīng)用程序部署到一個(gè)不規(guī)則的、普遍存在的環(huán)境中。我不需要觸發(fā)一個(gè) Web 容器甚至指定在哪里 部署應(yīng)用程序。(它位于 California、我的硬盤(pán)或者是月球上?)妙處在于這并不重要 — Google 負(fù)責(zé)處理這個(gè)問(wèn)題。注意,是解決所有問(wèn)題。此外,可以肯定的是,Google 已經(jīng)知道如何進(jìn)行全球性擴(kuò)展,這樣位于印度的用戶(hù)在查看應(yīng)用程序時(shí)會(huì)擁有和阿根廷用戶(hù)相同的體驗(yàn)。

綜上所述,您的確有必要牢記一些東西。Google 的基礎(chǔ)設(shè)施支持 Java 技術(shù),但是并不意味著所有內(nèi)容;如果您回憶一下多年前 J2ME 問(wèn)世的情景,那么 App Engine 的限制可能在本質(zhì)上有些類(lèi)似。也就是說(shuō),并非所有核心 Java 庫(kù)和相關(guān)開(kāi)源庫(kù)都受支持。如前所述,Hibernate 就不受支持(主要是因?yàn)槭褂?App Engine 時(shí),您無(wú)法擁有關(guān)系數(shù)據(jù)庫(kù))。我在使用某些內(nèi)置了 base64 編碼的開(kāi)源庫(kù)時(shí)還遇到了一些挑戰(zhàn)(Google 要求您使用它的 URL Fetch 服務(wù))。App Engine 是一個(gè)平臺(tái) — 您必須以它為方向進(jìn)行開(kāi)發(fā),就目前而言,這是一個(gè)單向的過(guò)程。

結(jié)束語(yǔ)

面向?qū)ο缶幊痰膭?chuàng)始人之一 Alan Kay 曾經(jīng)這樣說(shuō)道,“預(yù)測(cè)未來(lái)的最佳方式就是實(shí)現(xiàn)它”。我同意 Alan Kay 的這個(gè)說(shuō)法。不管其他人如何預(yù)測(cè) Java 技術(shù)的未來(lái),我認(rèn)為未來(lái)已經(jīng)在您的面前。

正如您在本文中了解的那樣,Google App Engine 正是面向未來(lái)的一個(gè)平臺(tái) — 假設(shè)您在其沙盒中試用。(注意,我只介紹了沙盒中的部分特性;App Engine 具有大量特性)。如果您希望獲得更多的靈活性(就是說(shuō),希望擁有一個(gè)關(guān)系數(shù)據(jù)庫(kù)并且必須使用 Hibernate),但是也希望借用其他人的可擴(kuò)展基礎(chǔ)設(shè)施,那么可以使用替代解決方案。Amazon 的 EC2 實(shí)際上就是位于按需使用的混合基礎(chǔ)設(shè)施上的虛擬服務(wù)器。您將在下個(gè)月的 Java 開(kāi)發(fā) 2.0 中了解它。

【編輯推薦】

  1. Google App Engine性能優(yōu)化策略:頁(yè)面性能優(yōu)化
  2. Google App Engine上的Scala+Lift初試
  3. 什么是GAE:Google App Engine介紹
  4. 手把手教你在Google App Engine上運(yùn)行PHP
  5. 開(kāi)始您的第一個(gè)Google App Engine應(yīng)用
責(zé)任編輯:yangsai 來(lái)源: IBMDW
相關(guān)推薦

2009-04-13 15:48:54

Google AppJavaSun

2010-02-01 09:21:49

GroovyGoogle App Gaelyk

2009-04-08 16:47:11

GoogleApp EngineJava

2009-04-09 08:54:07

App EnginegoogleJava

2009-04-09 09:53:43

GoogleAppEngineJava

2012-08-01 14:12:45

IBMdW

2009-06-26 16:32:22

App Engine文檔存儲(chǔ)文檔搜索

2009-09-02 11:34:09

Google App

2009-07-14 09:25:43

Google App GAEJava SDK 1.

2013-07-30 12:29:19

Google App Google技術(shù)Engine

2009-05-22 14:52:33

App Engine免費(fèi)配額

2009-08-11 11:23:41

什么是GAEGoogle App

2009-05-14 09:47:30

GoogleApp EngineJava SDK

2011-09-06 14:53:01

Google App

2009-04-14 11:01:33

GoogleApp EngineGroovy

2009-12-04 10:15:51

App Engine

2009-09-15 16:37:06

Google App 持久性

2009-09-07 10:42:01

Scala LiftGoogle App

2011-04-15 17:43:15

Google App Google

2009-04-09 11:06:00

GoogleApp EngineJVM
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

色是在线视频| 日韩一级中文字幕| 久久日文中文字幕乱码| 在线成人av网站| 亚洲熟妇无码av在线播放| 午夜视频在线播放| 精品一区二区三区在线播放| 九九热在线精品视频| 小毛片在线观看| 播放一区二区| 亚洲综合在线视频| 欧美午夜免费| 精品国产99久久久久久宅男i| 在线精品亚洲| 日韩视频永久免费观看| 久久精品aⅴ无码中文字字幕重口| 日本在线高清| 亚洲精品成人在线| 婷婷精品国产一区二区三区日韩| www.久久久久久久久久| 久久欧美肥婆一二区| 欧美成人在线免费视频| 亚洲精品一区二区三区影院忠贞| 久久9999免费视频| 在线观看国产日韩| 成人免费在线| 大桥未久在线播放| 亚洲国产成人私人影院tom| 亚洲自拍偷拍视频| 在线观看 亚洲| 欧美久久影院| 日韩小视频在线观看| 中文乱码人妻一区二区三区视频| 成人在线免费| 日本道在线观看一区二区| 超碰人人爱人人| 美女羞羞视频在线观看| 久久美女艺术照精彩视频福利播放| 91中文在线视频| 中文字幕一区二区三区免费看 | 久久韩国免费视频| 国产精品成人无码免费| 久久不见久久见国语| 亚洲高清久久网| 国产精品偷伦视频免费观看了| 久久福利在线| 欧美视频在线播放| wwwwww.色| 芒果视频成人app| 欧美性生交xxxxx久久久| 国产亚洲成aⅴ人片在线观看 | 欧美黄色三级| 亚洲美女在线一区| 一区二区在线不卡| 国家队第一季免费高清在线观看| 懂色av中文一区二区三区| 亚洲综合精品伊人久久| 国产精品主播一区二区| 国产在线国偷精品产拍免费yy| 国产精品爽黄69| 中国a一片一级一片| 日韩va亚洲va欧美va久久| 国产91精品在线播放| 少妇久久久久久久| 日韩国产在线观看一区| 国产精品99久久久久久久久久久久| 亚洲 欧美 成人| 久久精品综合| 国产精品自产拍在线观看| 一区二区的视频| 国产在线精品一区二区三区不卡| 999精品视频一区二区三区| www天堂在线| 成人h精品动漫一区二区三区| 国产伦精品一区二区| 亚洲欧美日韩免费| 国产区在线观看成人精品| 亚洲一区尤物| 国产偷倩在线播放| 欧美午夜美女看片| www.com黄色片| 久久亚洲精精品中文字幕| 精品粉嫩aⅴ一区二区三区四区| 秘密基地免费观看完整版中文| 国产一区调教| 在线观看日韩欧美| 男人的天堂久久久| 一级成人国产| 国产欧美精品一区二区三区-老狼 国产欧美精品一区二区三区介绍 国产欧美精品一区二区 | 一区二区三区日本视频| 日韩精品在线一区二区| 国产精品一区二区入口九绯色| 精品国产aⅴ| 欧美精品亚州精品| 日韩人妻精品中文字幕| 国内精品国产三级国产a久久| 国产伦精品一区二区三区视频孕妇 | 视频一区视频二区国产精品| 日本一级二级视频| 久久国产精品久久w女人spa| 91在线观看免费| 欧洲综合视频| 一区二区久久久久| 91国产精品视频在线观看| **爰片久久毛片| 尤物九九久久国产精品的特点| 免费在线黄色网| 久久一区二区三区四区五区| 亚洲free嫩bbb| 国产福利片在线| 亚洲网友自拍偷拍| 久久久久久久久久久久久久久国产 | 亚洲精品白浆| 欧美亚一区二区| 亚洲欧美日韩偷拍| 中文字幕日韩欧美精品高清在线| 欧洲成人在线视频| 男人天堂网在线视频| 国产精品蜜臀av| 国内外成人激情视频| 国产日韩欧美中文在线| 国产一区二区三区毛片| 国产超碰人人爽人人做人人爱| 国产一区二区三区不卡在线观看| 日本在线成人一区二区| 九九精品调教| 91精品免费在线观看| 性欧美一区二区| 亚洲欧美清纯在线制服| 国产精品视频免费一区二区三区| 大地资源网3页在线观看| 欧美日韩亚洲综合在线| 欧美熟妇激情一区二区三区| 日韩亚洲国产精品| 国产精品手机视频| 欧美xxx黑人xxx水蜜桃| 日韩一区二区三| 国产黄色的视频| 国产一区在线不卡| 亚洲成人动漫在线| 高清一区二区| 久久久成人精品| 国产又粗又猛又黄| 国产精品女主播av| 另类小说色综合| 日韩欧美1区| 国产日韩换脸av一区在线观看| 国内三级在线观看| 91福利资源站| 国产又粗又黄又猛| 蜜桃久久久久久久| 在线视频91| 精品亚洲二区| 欧美精品videos性欧美| 黄色av网站免费在线观看| 亚洲综合激情另类小说区| 久久久久久无码精品人妻一区二区| 88国产精品视频一区二区三区| 91精品国产综合久久香蕉922| 午夜视频在线观看网站| 在线不卡一区二区| 久久久久久久久毛片| 国产福利视频一区二区三区| 欧美视频在线第一页| 加勒比色综合久久久久久久久| 国内精品模特av私拍在线观看| 四虎精品一区二区三区| 狠狠综合久久av一区二区小说 | 亚洲精品一区二区三区新线路| 亚洲资源中文字幕| 精品国产一区在线| 三级不卡在线观看| 国产精品久久成人免费观看| 日韩视频1区| 26uuu亚洲国产精品| 黄色av网站在线免费观看| 欧美日韩亚洲国产综合| 欧美xxxx黑人xyx性爽| 成人国产免费视频| 天堂av在线网站| 午夜视频精品| 欧美日韩另类丝袜其他| 色综合久久久| 国内外成人免费激情在线视频网站| 四虎影院在线域名免费观看| 在线观看亚洲一区| 久久免费公开视频| 久久久www成人免费毛片麻豆| 嫩草视频免费在线观看| 在线观看一区视频| 亚洲最大免费| 欧美天堂社区| 91九色综合久久| 中文在线аv在线| 精品国产一区二区三区久久| 欧美一级做性受免费大片免费| 欧美系列日韩一区| 久久视频免费在线观看| 国产精品色噜噜| 成人在线视频免费播放| 捆绑调教美女网站视频一区| 九九爱精品视频| 一区二区三区午夜视频| 欧美日本亚洲| 日韩三级网址| 成人在线免费观看视视频| 一二三四视频在线中文| 久久最新资源网| 成人在线观看一区| 亚洲精品美女网站| 不卡的日韩av| 欧美精品少妇一区二区三区| 中文字幕视频网| 一区二区三区免费| 男人晚上看的视频| 久久精品日产第一区二区三区高清版| 国产chinesehd精品露脸| 毛片av中文字幕一区二区| 国产特级黄色大片| 韩日精品视频| 波多野结衣 作品| 国产精品久久久久久| 日韩电影在线播放| 色橹橹欧美在线观看视频高清| 亚洲一区二区在线| 香蕉久久久久久| 国产精品视频免费在线观看| 小视频免费在线观看| 久久久久久久久中文字幕| 国产精品刘玥久久一区| 中文在线资源观看视频网站免费不卡| 青青青手机在线视频观看| 亚洲大胆人体在线| 好吊色在线观看| 精品不卡在线视频| 亚洲国产精品欧美久久| 日韩欧美中文字幕一区| 国产一区二区三区在线观看| 欧美日韩在线三区| 在线观看黄色网| 欧美三区在线视频| 自拍偷拍福利视频| 欧美日韩在线播| 中文字幕一区二区三区四区视频| 色网站国产精品| 销魂美女一区二区| 欧洲生活片亚洲生活在线观看| 日本a级c片免费看三区| 色88888久久久久久影院野外| 国产精品男女视频| 色就色 综合激情| 中文字幕av片| 在线播放/欧美激情| 99热这里只有精品在线观看| 在线不卡的av| www.看毛片| 亚洲精品www久久久| 天天色综合av| 亚洲女人天堂视频| a中文在线播放| 久久精品国产成人| 免费在线观看av电影| 久久久久久伊人| 中文日产幕无线码一区二区| 亲子乱一区二区三区电影 | 国产视频一区在线观看一区免费| 欧美二区在线视频| 午夜亚洲伦理| 第四色婷婷基地| 国产91富婆露脸刺激对白| 老司机午夜免费福利| 26uuu亚洲婷婷狠狠天堂| 永久免费av无码网站性色av| 最新国产精品久久精品| 久久综合亚洲色hezyo国产| 欧美日韩免费看| 在线观看国产黄| 亚洲精品一区二区三区精华液 | 久久精品夜夜夜夜夜久久| 欧美四级在线| 欧洲成人在线观看| 蜜桃精品一区二区三区| 精品国产一区二区三| 成人中文在线| 免费网站在线观看视频| 免费视频一区| 欧美性受xxxxxx黑人xyx性爽| 大尺度一区二区| 国产精品免费无码| 一区二区三区在线视频播放| 国产成人精品网| 欧美一级理论片| 九色视频在线观看免费播放| 久久久国产视频| 欧美aa视频| 成人3d动漫一区二区三区91| 免费电影一区二区三区| 4444在线观看| 日本少妇一区二区| www.男人天堂| 亚洲美女淫视频| 国产情侣呻吟对白高潮| 亚洲成人av在线| 国产在线观看a视频| 国产91久久婷婷一区二区| 亚洲精品aⅴ| 一本一道久久a久久精品综合| 亚洲国产一区二区精品专区| mm131国产精品| 2欧美一区二区三区在线观看视频| 天天操天天操天天操天天操天天操| 欧美日韩免费在线| 亚洲国产精品视频在线| 日韩中文字幕在线视频| 欧美日韩123区| 狠狠色噜噜狠狠色综合久| 午夜精品免费| 久久久久久综合网| 亚洲国产精品成人综合色在线婷婷 | 欧美午夜丰满在线18影院| 精品久久久久久亚洲综合网站| 一本大道久久加勒比香蕉| 美女av在线免费看| 国产福利不卡| 欧美日本国产| a级大片免费看| 亚洲少妇中出一区| 在线观看中文字幕码| 亚洲人高潮女人毛茸茸| 黄频免费在线观看| 国产伦精品一区二区三区高清版| 综合在线视频| 久久久精品视频国产| 综合婷婷亚洲小说| 91在线精品入口| www.国产精品一二区| 国产第一精品| 婷婷四月色综合| 精品在线观看免费| 美国一级片在线观看| 精品视频一区三区九区| 91精彩视频在线观看| 国产欧美日韩精品丝袜高跟鞋| 精品国产一区二区三区av片| 少妇高清精品毛片在线视频 | 精品国产国产综合精品| 欧美性受xxxx黑人xyx性爽| 国产女人在线观看| 国产精品久久久久7777婷婷| 精品久久91| 91 在线视频观看| 亚洲情趣在线观看| 国产a级免费视频| 欧美大学生性色视频| 国内露脸中年夫妇交换精品| 精品国产一二三四区| 久久女同精品一区二区| 日韩av免费播放| 久久精品国产电影| 成人搞黄视频| 免费观看日韩毛片| 亚洲国产精品成人综合色在线婷婷 | 日韩欧美精品一区二区| 青青草视频一区| 国产美女福利视频| 精品国精品自拍自在线| 色戒汤唯在线观看| 亚洲啪啪av| 国产精品99久| 五月天综合激情| 日韩在线视频观看| 亚洲天堂中文字幕在线观看| 免费av手机在线观看| 国产偷国产偷亚洲高清人白洁| 中文字幕av免费观看| 九色91av视频| 欧美人妖在线| 日本网站在线看| 五月婷婷激情综合| 北岛玲一区二区三区| 97久草视频| 久久精品毛片| 欧美一区免费观看| 日韩成人在线视频观看| 国精品产品一区| av日韩一区二区三区| 国产精品素人视频| 日韩一级片免费| 成人久久一区二区三区| 亚洲视频www| 任我爽在线视频| 日韩毛片在线观看| 美国十次综合久久| 中文字幕在线导航| 亚洲国产中文字幕在线视频综合 | 一呦二呦三呦国产精品| 亚洲第一区第二区第三区| 欧美午夜激情视频| 国产www视频在线观看| 亚洲欧美日韩另类精品一区二区三区 |