本文介紹 Translator 模式,并說明如何在 JSP 技術(shù)和 servlet 環(huán)境中使用 Translator 模式。讀完本文以后,您將能夠利用本文提供的代碼示例成功實(shí)現(xiàn)這一模式。
在使用 JSP 文件和 servlet 構(gòu)建 Web 應(yīng)用程序時(shí),應(yīng)用程序的界面多半會(huì)是 HTML。瀏覽器翻譯后的HTML 就是一個(gè)大型字符串。構(gòu)成應(yīng)用程序的業(yè)務(wù)對(duì)象只有少數(shù)屬性為字符串,其余屬性則為日期、數(shù)字甚至其他業(yè)務(wù)對(duì)象。在構(gòu)建 Web 應(yīng)用時(shí),如何將業(yè)務(wù)對(duì)象所包含的信息轉(zhuǎn)換為瀏覽器可識(shí)別的 HTML 是個(gè)大問題。幾乎每個(gè)應(yīng)用程序都會(huì)以 HTML 格式收集信息,而這些信息又會(huì)作為字符串發(fā)送給服務(wù)器。因此現(xiàn)在還存在如何將所提交的信息轉(zhuǎn)換為業(yè)務(wù)對(duì)象可識(shí)別的值這一問題。
Translator 模式通過提供一個(gè)與 JSP 文件、servlet 和業(yè)務(wù)對(duì)象協(xié)同工作的Translator 對(duì)象解決了這兩個(gè)問題。Translator 對(duì)象將三個(gè)不同對(duì)象結(jié)合在一起,從而使每個(gè)對(duì)象都專用于完成一項(xiàng)給定的任務(wù)。Translator 對(duì)象之所以可充當(dāng)這個(gè)紐帶,是因?yàn)樗庋b了要完成的全部轉(zhuǎn)換邏輯。JSP 文件與 Translator 對(duì)象通信,專用于顯示信息。這使 JSP 文件變得比較“干凈”,即 JSP 文件中幾乎沒有 Java 代碼。servlet 專門處理業(yè)務(wù)對(duì)象的持久性和屏幕之間的導(dǎo)航流。有了 servlet 專門處理這些任務(wù),JSP 文件就幾乎不需要 Java 代碼了,從而使 JSP 文件變得更加“干凈”.更詳細(xì)一點(diǎn),如前所述Translator 模式由三個(gè)基本部分組成,分別是專用的 Translator 對(duì)象、servlet 和 JSP 文件。
JSP 文件的職責(zé)就是充當(dāng)用戶界面類。這是可能的,因?yàn)?JSP 文件從 Translator 對(duì)象獲取預(yù)先格式化好的字符串值(稍后討論)。JSP 文件應(yīng)包含盡可能少的 Java 代碼,因?yàn)樨?fù)責(zé)開發(fā) JSP 文件的網(wǎng)頁(yè)設(shè)計(jì)者通常對(duì) Java 編程語(yǔ)言知之甚少,或者干脆就一無所知。使內(nèi)嵌在 JSP 文件中的 Java 代碼盡可能達(dá)到最少,這樣就使 JSP 文件更像純 HTML 頁(yè)面。與整篇都糾纏著 Java 代碼的 JSP 文件相比,純 HTML 頁(yè)面的修改要容易得多。
Translator 對(duì)象是一種專用的類,它類似于 MVC 模式中的模型 (model) 類。Translator 對(duì)象將業(yè)務(wù)對(duì)象與 JSP 文件中的顯示域聯(lián)系起來。網(wǎng)頁(yè)設(shè)計(jì)者將調(diào)用 Translator 對(duì)象的一個(gè) getter 方法在 JSP 文件中顯示動(dòng)態(tài)信息。Translator 對(duì)象將返回一個(gè)預(yù)先格式化好的字符串,因此網(wǎng)頁(yè)設(shè)計(jì)者需要做的全部工作就是將它發(fā)送到一個(gè)輸出流中。Translator 對(duì)象能夠提供此信息,因?yàn)樗趦?nèi)部變量中存儲(chǔ)著需要顯示的全部值。這些變量是由 syncGuiToModel() 和 processForm() 方法設(shè)置的。這兩個(gè)方法專門處理屏幕和 Translator 之間的信息同步。小組中的 Java 開發(fā)人員負(fù)責(zé)構(gòu)建這個(gè) Translator 對(duì)象。
最后,servlet 專用于處理導(dǎo)航流和業(yè)務(wù)對(duì)象的持久性。當(dāng) servlet 接收到提交表單時(shí),它將獲得 Translator 對(duì)象的一個(gè)實(shí)例,并使用 processForm() 方法將對(duì)表單的分析委派給 Translator 對(duì)象。在表單的分析完成以后,servlet 就會(huì)讓 Translator 對(duì)象使用 syncModelToGui() 方法將業(yè)務(wù)對(duì)象的值同步為表單中所提交的值。在成功轉(zhuǎn)換所提交的值并將它們?cè)O(shè)置到業(yè)務(wù)對(duì)象上之后,servlet 將對(duì)業(yè)務(wù)對(duì)象執(zhí)行持久化,并向網(wǎng)頁(yè)訪問者顯示確認(rèn)頁(yè)。
給我顯微鏡
下面我們仔細(xì)查看 Translator 模式的三個(gè)部分:JSP 文件、servlet 和 Translator 對(duì)象。(本文的示例遵循的是 Servlet 2.1 規(guī)范和 JSP 1.0 規(guī)范。這些示例是在 WebSphere 3.02 和 WebSphere 3.5 環(huán)境下構(gòu)建和測(cè)試的。)
JSP 文件
使用 Translator 模式的典型 JSP 輸入表單如下所示:
<%@ page extends="com.ibm.igs.ispkcm.translator.JspBase"
import="com.ibm.developerworks.translatorpattern.LoanTranslator,
Java.util.Hashtable"%>
<%
LoanTranslator ltLoan = LoanTranslator.getInstance(request);
Hashtable htErrors = ltLoan.getErrors();
%>
<%= displayErrors(htErrors) %>
<%= hightLightErrors(ltLoan.BORROWER_LAST_NAME, htErrors) %>Borrower Last Name:
value="<%= ltLoan.getBorrowerLastName() %>">
在 Translator 模式中,所有表單都是 JSP 文件,而非 HTML 文件,所以輸入域的值可以是動(dòng)態(tài)的。這一點(diǎn)很重要,因?yàn)槲覀兙W(wǎng)站的訪問者是實(shí)實(shí)在在的人,他們會(huì)犯輸入錯(cuò)誤。比讓網(wǎng)站通知您它不接受您的輸入更糟糕的一件事情是,讓它通知您它不接受您在某個(gè)域中輸入的內(nèi)容,并要求您重新鍵入其他 20 個(gè)域,因?yàn)槟硞€(gè)程序員正忙于檢查股市報(bào)價(jià),沒有時(shí)間來提高輸入表單的用戶友好性。在Translator 模式中,輸入表單的每個(gè)輸入域的值都是動(dòng)態(tài)設(shè)置的,因此如果因存在輸入錯(cuò)誤而需要向網(wǎng)站訪問者重新顯示輸入頁(yè),他們就會(huì)看到突出顯示的錯(cuò)誤,但其他輸入項(xiàng)仍然保留。
在使用 JSP 文件和 servlet 構(gòu)建 Web 應(yīng)用程序時(shí),應(yīng)用程序的界面多半會(huì)是 HTML。瀏覽器翻譯后的HTML 就是一個(gè)大型字符串。構(gòu)成應(yīng)用程序的業(yè)務(wù)對(duì)象只有少數(shù)屬性為字符串,其余屬性則為日期、數(shù)字甚至其他業(yè)務(wù)對(duì)象。在構(gòu)建 Web 應(yīng)用時(shí),如何將業(yè)務(wù)對(duì)象所包含的信息轉(zhuǎn)換為瀏覽器可識(shí)別的 HTML 是個(gè)大問題。幾乎每個(gè)應(yīng)用程序都會(huì)以 HTML 格式收集信息,而這些信息又會(huì)作為字符串發(fā)送給服務(wù)器。因此現(xiàn)在還存在如何將所提交的信息轉(zhuǎn)換為業(yè)務(wù)對(duì)象可識(shí)別的值這一問題。
Translator 模式通過提供一個(gè)與 JSP 文件、servlet 和業(yè)務(wù)對(duì)象協(xié)同工作的Translator 對(duì)象解決了這兩個(gè)問題。Translator 對(duì)象將三個(gè)不同對(duì)象結(jié)合在一起,從而使每個(gè)對(duì)象都專用于完成一項(xiàng)給定的任務(wù)。Translator 對(duì)象之所以可充當(dāng)這個(gè)紐帶,是因?yàn)樗庋b了要完成的全部轉(zhuǎn)換邏輯。JSP 文件與 Translator 對(duì)象通信,專用于顯示信息。這使 JSP 文件變得比較“干凈”,即 JSP 文件中幾乎沒有 Java 代碼。servlet 專門處理業(yè)務(wù)對(duì)象的持久性和屏幕之間的導(dǎo)航流。有了 servlet 專門處理這些任務(wù),JSP 文件就幾乎不需要 Java 代碼了,從而使 JSP 文件變得更加“干凈”.更詳細(xì)一點(diǎn),如前所述Translator 模式由三個(gè)基本部分組成,分別是專用的 Translator 對(duì)象、servlet 和 JSP 文件。
JSP 文件的職責(zé)就是充當(dāng)用戶界面類。這是可能的,因?yàn)?JSP 文件從 Translator 對(duì)象獲取預(yù)先格式化好的字符串值(稍后討論)。JSP 文件應(yīng)包含盡可能少的 Java 代碼,因?yàn)樨?fù)責(zé)開發(fā) JSP 文件的網(wǎng)頁(yè)設(shè)計(jì)者通常對(duì) Java 編程語(yǔ)言知之甚少,或者干脆就一無所知。使內(nèi)嵌在 JSP 文件中的 Java 代碼盡可能達(dá)到最少,這樣就使 JSP 文件更像純 HTML 頁(yè)面。與整篇都糾纏著 Java 代碼的 JSP 文件相比,純 HTML 頁(yè)面的修改要容易得多。
Translator 對(duì)象是一種專用的類,它類似于 MVC 模式中的模型 (model) 類。Translator 對(duì)象將業(yè)務(wù)對(duì)象與 JSP 文件中的顯示域聯(lián)系起來。網(wǎng)頁(yè)設(shè)計(jì)者將調(diào)用 Translator 對(duì)象的一個(gè) getter 方法在 JSP 文件中顯示動(dòng)態(tài)信息。Translator 對(duì)象將返回一個(gè)預(yù)先格式化好的字符串,因此網(wǎng)頁(yè)設(shè)計(jì)者需要做的全部工作就是將它發(fā)送到一個(gè)輸出流中。Translator 對(duì)象能夠提供此信息,因?yàn)樗趦?nèi)部變量中存儲(chǔ)著需要顯示的全部值。這些變量是由 syncGuiToModel() 和 processForm() 方法設(shè)置的。這兩個(gè)方法專門處理屏幕和 Translator 之間的信息同步。小組中的 Java 開發(fā)人員負(fù)責(zé)構(gòu)建這個(gè) Translator 對(duì)象。
最后,servlet 專用于處理導(dǎo)航流和業(yè)務(wù)對(duì)象的持久性。當(dāng) servlet 接收到提交表單時(shí),它將獲得 Translator 對(duì)象的一個(gè)實(shí)例,并使用 processForm() 方法將對(duì)表單的分析委派給 Translator 對(duì)象。在表單的分析完成以后,servlet 就會(huì)讓 Translator 對(duì)象使用 syncModelToGui() 方法將業(yè)務(wù)對(duì)象的值同步為表單中所提交的值。在成功轉(zhuǎn)換所提交的值并將它們?cè)O(shè)置到業(yè)務(wù)對(duì)象上之后,servlet 將對(duì)業(yè)務(wù)對(duì)象執(zhí)行持久化,并向網(wǎng)頁(yè)訪問者顯示確認(rèn)頁(yè)。
給我顯微鏡
下面我們仔細(xì)查看 Translator 模式的三個(gè)部分:JSP 文件、servlet 和 Translator 對(duì)象。(本文的示例遵循的是 Servlet 2.1 規(guī)范和 JSP 1.0 規(guī)范。這些示例是在 WebSphere 3.02 和 WebSphere 3.5 環(huán)境下構(gòu)建和測(cè)試的。)
JSP 文件
使用 Translator 模式的典型 JSP 輸入表單如下所示:
<%@ page extends="com.ibm.igs.ispkcm.translator.JspBase"
import="com.ibm.developerworks.translatorpattern.LoanTranslator,
Java.util.Hashtable"%>
<%
LoanTranslator ltLoan = LoanTranslator.getInstance(request);
Hashtable htErrors = ltLoan.getErrors();
%>
<%= displayErrors(htErrors) %>
<%= hightLightErrors(ltLoan.BORROWER_LAST_NAME, htErrors) %>Borrower Last Name:
value="<%= ltLoan.getBorrowerLastName() %>">
在 Translator 模式中,所有表單都是 JSP 文件,而非 HTML 文件,所以輸入域的值可以是動(dòng)態(tài)的。這一點(diǎn)很重要,因?yàn)槲覀兙W(wǎng)站的訪問者是實(shí)實(shí)在在的人,他們會(huì)犯輸入錯(cuò)誤。比讓網(wǎng)站通知您它不接受您的輸入更糟糕的一件事情是,讓它通知您它不接受您在某個(gè)域中輸入的內(nèi)容,并要求您重新鍵入其他 20 個(gè)域,因?yàn)槟硞€(gè)程序員正忙于檢查股市報(bào)價(jià),沒有時(shí)間來提高輸入表單的用戶友好性。在Translator 模式中,輸入表單的每個(gè)輸入域的值都是動(dòng)態(tài)設(shè)置的,因此如果因存在輸入錯(cuò)誤而需要向網(wǎng)站訪問者重新顯示輸入頁(yè),他們就會(huì)看到突出顯示的錯(cuò)誤,但其他輸入項(xiàng)仍然保留。