精品欧美一区二区三区在线观看 _久久久久国色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无码一区二区三区人| 免费成人进口网站| 亚洲黄色免费观看| 久久视频精品| 欧美精品一区二区高清在线观看| 成人午夜精品久久久久久久蜜臀| 国产三级在线看| 国产精品自在欧美一区| 777精品视频| 久久一级免费视频| 国产一区丝袜| 欧美日韩国产片| 九一国产精品视频| 色网站在线看| 成人av动漫在线| 国产精品普通话| 亚洲免费激情视频| 色一区二区三区四区| 亚洲大胆人体av| 色噜噜狠狠永久免费| av资源一区| 亚洲视频精选在线| 久久国产主播精品| www.欧美国产| 另类专区欧美蜜桃臀第一页| 777午夜精品福利在线观看| 日韩成人短视频| 国产精品自拍区| 欧美精品一区二区三区蜜臀| 国产无遮挡猛进猛出免费软件| 都市激情国产精品| 亚洲精品国产精品乱码不99| 亚洲成人在线视频网站| 午夜在线视频观看| 国产一区二区电影| 国产精品色视频| 久久av高潮av无码av喷吹| 手机亚洲手机国产手机日韩| 亚洲天堂av高清| 色婷婷免费视频| 91精品尤物| 91精品在线免费观看| 欧美精品aaaa| 666av成人影院在线观看| 欧美日韩在线视频首页| 男女超爽视频免费播放| 丰满诱人av在线播放| 亚洲综合色成人| 成年在线观看视频| 在线午夜影院| 一区二区三区在线免费| 波多野结衣激情| 久久久久久国产精品免费无遮挡| 国产精品色在线| 日韩一二三区不卡在线视频| 成年人视频网站在线| 国产三级欧美三级日产三级99| 欧美一级爽aaaaa大片| 日本不卡视频一区二区| 久久久久国产精品厨房| 日本不卡一区二区三区视频| 国产免费a∨片在线观看不卡| 久久嫩草精品久久久精品| 欧美日韩一区二区视频在线观看| 欧美巨乳在线| 欧美激情在线一区二区三区| 亚洲国产精品一区二区第四页av| 9191在线观看| 亚洲免费在线观看| 久久在线中文字幕| 亚洲三级欧美| 在线一区二区三区四区五区| 成人免费在线观看视频网站| 欧美在线se| 日韩欧美精品三级| 中文字幕在线视频播放| 亚洲瘦老头同性70tv| 在线电影中文日韩| www.99re7| 日韩视频二区| 国产精品日日做人人爱| 国产乱色精品成人免费视频| 成人午夜视频在线观看| 欧美日韩国产免费一区二区三区 | 麻豆精品蜜桃| 欧美日韩国产一二三| 性活交片大全免费看| 婷婷精品在线观看| 色婷婷综合久久久久| 欧美精品一区二区成人| 亚洲欧美日韩国产| 国产日韩av在线播放| 国内爆初菊对白视频| 久久精品人人做人人综合| 在线国产99| 欧美另类老肥妇| 欧美在线不卡一区| 国产精品嫩草69影院| 欧美久久综合网| 欧美国产日韩精品| 在线免费观看一区二区| 成人美女视频在线观看18| 日韩精品一区二区三区外面| 日韩精品分区| 欧美日韩精品电影| 日韩片在线观看| 亚洲最大av| 国产成人欧美在线观看| 亚洲精品国产一区二| 国产日韩欧美综合在线| 阿v天堂2018| 亚洲精品大全| 亚洲天堂av女优| 日本三级视频在线| 国产主播一区二区| 日本一区视频在线| 超碰91在线观看| 69堂精品视频| 天堂在线中文视频| 国产欧美日本| 国产精品一区在线观看| 国产成人l区| 欧洲av一区二区嗯嗯嗯啊| 中国一级特黄录像播放| 伊人情人综合网| 国产精品久久久久久亚洲影视| 天天干天天色天天| 亚洲一区二区三区视频在线播放| 激情黄色小视频| 欧美熟乱15p| 欧美在线视频免费播放| 欧美一区二区三区黄片| 亚洲一区精品在线| 国产又粗又猛又爽又黄| 日韩欧美伦理| 国产精品v日韩精品| 四虎国产精品永远| 亚洲综合成人在线| 国产在线观看免费播放| 亚洲欧美综合国产精品一区| 91网站免费观看| 91美女视频在线| 欧美三级乱人伦电影| 69视频在线观看免费| 午夜一区在线| 欧美极品视频一区二区三区| 中文在线а√在线8| 亚洲精品久久久久久久久久久久| 国产性猛交普通话对白| 国产高清亚洲一区| 大荫蒂性生交片| 一区二区在线视频观看| 欧美精品福利视频| 欧美一区二区黄片| 日韩欧美成人免费视频| aa片在线观看视频在线播放| 国产精品视区| 奇米精品在线| 男人亚洲天堂| 久久色在线播放| 国产肥老妇视频| 亚洲精品中文在线影院| 激情av中文字幕| 一区二区精品| 日韩久久久久久久久久久久久| a屁视频一区二区三区四区| 最近2019中文免费高清视频观看www99| 中文字幕av无码一区二区三区| 中文字幕中文字幕中文字幕亚洲无线| 午夜免费看视频| 欧美精品91| 欧美黑人xxxxx| 美女久久久久久| 超碰精品一区二区三区乱码| 性一交一乱一伧老太| 午夜激情久久久| 一区二区精品免费| 久久99精品久久久久婷婷| av 日韩 人妻 黑人 综合 无码| 成人香蕉社区| 国产精品高潮呻吟视频| 国产在线看片| 亚洲激情在线视频| 中文字幕永久在线视频| 亚洲人成小说网站色在线| 黄色激情在线观看| 日本sm残虐另类| 毛片av在线播放| 亚洲桃色综合影院| 51国偷自产一区二区三区| 欧美一级鲁丝片| 久久久精品久久久久| 天天操天天干天天爽| 欧美日韩一区国产| 日本三级免费看| 国产精品久久久爽爽爽麻豆色哟哟| 国产精品19p| 男人的天堂久久精品| 久久人人爽人人爽人人av| 黄色不卡一区| 国产精品一 二 三| 日本久久久久| 欧美最猛性xxxx| 日韩av官网| 中文字幕av一区中文字幕天堂 | 日本三级网站在线观看| 欧美国产日韩一二三区| 欧美日韩人妻精品一区在线| 美国三级日本三级久久99 | heyzo高清中文字幕在线| 中文字幕一区电影| 三级视频网站在线| 日韩欧美国产综合| 在线观看毛片av| 欧美特级www| 久久网中文字幕| 亚洲欧美中日韩| 欧美三级视频网站| 99久久综合狠狠综合久久| 青娱乐国产精品视频| 日本美女一区二区| 色综合av综合无码综合网站| 在线国产精品一区| 经典三级在线视频| 成人羞羞在线观看网站| 欧美日韩在线精品| 希岛爱理av免费一区二区| 99久久国产免费免费| 欧美日韩破处视频| 国产美女主播一区| 色猫猫成人app| 国产99久久精品一区二区永久免费 | 91欧美一区二区| 好吊操视频这里只有精品| 激情成人午夜视频| 国产精品视频中文字幕| 蜜桃传媒麻豆第一区在线观看| 日本免费黄视频| 一区二区三区国产盗摄| 久久视频这里有精品| 亚洲另类视频| 国产人妻777人伦精品hd| 在线精品福利| 亚洲熟妇无码一区二区三区| 最新成人av网站| 僵尸世界大战2 在线播放| 欧美日本一区二区高清播放视频| 欧美一级特黄aaaaaa在线看片| 久久久久久久久久久久久久久久久久| 亚洲精品一区二区毛豆| 久久精品国产68国产精品亚洲| 亚洲日本欧美在线| 欧美a级成人淫片免费看| 亚洲在线播放电影| 99热国内精品| 国产一二三四五| 欧美日本一区| 日韩av中文字幕第一页| 一本色道久久综合亚洲精品不卡 | 亚洲精品欧洲精品| 亚洲九九在线| 日本大片免费看| 夜久久久久久| 国产精品无码一本二本三本色| 欧美aaa在线| 奇米777在线| 丁香婷婷综合五月| 五月婷婷综合在线观看| 欧美激情一区二区三区在线| 久久99久久99精品免费看小说| 亚洲精品国产一区二区精华液 | 日韩免费啪啪| 九色精品美女在线| 成人免费图片免费观看| 国产97在线观看| 精品国产一级| 精品久久久三级| 日本成人小视频| 欧美日韩中文字幕在线播放| 国产日韩欧美| 中文字幕永久有效| 成人免费视频视频| 西西444www无码大胆| 亚洲图片欧美激情| 国产成人在线观看网站| 91国偷自产一区二区三区成为亚洲经典 | 超碰在线最新| 97超级碰在线看视频免费在线看| 国产成+人+综合+亚洲欧美| 亚洲a级在线观看| 亚洲电影一级片| 操bbb操bbb| 免费在线日韩av| 三日本三级少妇三级99| 99久久99久久久精品齐齐| 成人一级黄色大片| 欧美性精品220| 精品国自产拍在线观看| 亚洲毛片一区二区| 日皮视频在线观看| 国产精品免费在线免费| 加勒比色老久久爱综合网| 视频在线一区二区三区| 狠狠综合久久| 国产精品igao| 99久久国产综合色|国产精品| 天天操夜夜操av| 91久久国产综合久久| 男人天堂综合网| 久久久av网站| 小黄鸭精品aⅴ导航网站入口| 91香蕉视频在线下载| 精品视频97| 日本精品免费在线观看| 处破女av一区二区| 登山的目的在线| 91福利精品视频| 亚洲 精品 综合 精品 自拍| 欧美激情国内偷拍| 自拍偷拍亚洲| 亚洲国产精品日韩| 天堂va蜜桃一区二区三区| 插我舔内射18免费视频| 一区二区三区精品视频在线| 国产又色又爽又黄又免费| 亚洲香蕉av在线一区二区三区| 蜜桃视频在线观看免费视频| 成人片在线免费看| 一区二区三区午夜探花| 在线观看日本一区二区| 国产日本亚洲高清| 国产亚洲欧美在线精品| 精品中文视频在线| 福利影院在线看| 国产日韩一区二区三区| 国产一区欧美| 精品伦一区二区三区| 亚洲老妇xxxxxx| 精品国产亚洲一区二区麻豆| 操人视频在线观看欧美| 国模大尺度视频一区二区| 正在播放久久| 国产在线播放一区| 三级av在线免费观看| 91精品国产综合久久小美女| 午夜视频在线观看免费视频| 国产欧洲精品视频| 欧美1级片网站| 欧美性受xxxx黒人xyx性爽| 自拍偷拍亚洲综合| 国产视频第二页| 欧美放荡办公室videos4k| 一区二区三区视频播放| 日韩av在线播放不卡| 成人黄色av电影| 日韩特级黄色片| 国产一区二区三区视频在线观看 | 精品欧美激情精品一区| 亚洲 另类 春色 国产| 清纯唯美亚洲激情| 日韩欧美中字| 波多野结衣在线免费观看| 亚洲精品ww久久久久久p站| 亚洲乱色熟女一区二区三区| 午夜精品理论片| 欧美美乳视频| 伊人网在线综合| 一区二区三区免费在线观看| 特黄aaaaaaaaa真人毛片| 国产精品777| 天堂美国久久| fc2成人免费视频| 91极品美女在线| 国产黄色小视频在线| 国产精品视频免费一区| 美女黄色成人网| 麻豆天美蜜桃91| 亚洲精品久久久久中文字幕欢迎你 | 午夜宅男在线视频| 一区二区三区在线视频观看58| 头脑特工队2免费完整版在线观看| 国产成人福利网站| 综合久久一区| 精品无码在线视频| 欧美精品日韩精品| 欧美男男tv网站在线播放| 视频在线精品一区| 成人精品免费网站| 久久精品国产亚洲av麻豆蜜芽| 欧美插天视频在线播放| 自拍偷拍一区| 色哟哟免费视频| 疯狂欧美牲乱大交777| 免费黄色电影在线观看| 精品久久精品久久| 极品少妇xxxx偷拍精品少妇| 天堂网av手机版| 久久国产精品久久久久| 欧美欧美黄在线二区| 久久久久久无码精品人妻一区二区|