溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

用Java程序生成文本的捷徑(轉(zhuǎn))

發(fā)布時(shí)間:2020-08-10 15:02:01 來(lái)源:ITPUB博客 閱讀:145 作者:BSDLite 欄目:編程語(yǔ)言
用Java程序生成文本的捷徑(轉(zhuǎn))[@more@]大多數(shù)程序都需要輸出一些文本,比如郵件消息、HTML文件或控制臺(tái)輸出。但是,計(jì)算機(jī)本質(zhì)上只能處理二進(jìn)制數(shù)據(jù),程序員必須讓軟件來(lái)生成可理解的文本。在這篇文章中,我要介紹的是在生成和輸出文本時(shí),為何使用模板引擎能夠節(jié)省時(shí)間。你將了解模板的優(yōu)點(diǎn),如何針對(duì)不同的情形創(chuàng)建高效的模板。和 System.println說(shuō)再見(jiàn)! 雖然程序員可以很輕松地編寫(xiě)出輸出文字信息的代碼(因?yàn)檫@畢竟是從Hello World范例學(xué)到的第一件事情),但通常而言,程序員不是寫(xiě)作或組織文字信息(如郵件)的最佳人選。因此,我們常常讓市場(chǎng)部門(mén)或公關(guān)部門(mén)去做那些事情。但遺憾的是,即使對(duì)于最普通的郵件,編寫(xiě)者也常常依賴程序輸出來(lái)完成任務(wù)。無(wú)論是對(duì)于郵件編寫(xiě)者還是程序員,這種合作方式都很容易帶來(lái)誤解和造成失誤。 請(qǐng)看一個(gè)例子:一個(gè)Java程序從某個(gè)數(shù)據(jù)源收集一些客戶信息,通過(guò)email給公司的每一個(gè)客戶發(fā)送帳戶余額信息。下面是完成這個(gè)任務(wù)的Java程序(完整的示例程序代碼可以從本文最后下載): for (int i=0; i { Customer customer = (Customer)customers.get(i); StringBuffer message = new StringBuffer(); message.append ("尊敬的先生/女士: "); message.append (customer.getCustName()); message.append (" "); message.append (" "); message.append ("您的帳戶余額是 "); message.append (customer.getAccountTotal()); message.append (" "); message.append (" "); message.append ("致禮!"); message.append (" "); message.append ("某某裝飾品公司"); // 發(fā)送email mm.sendMail (customer.getFirstName(), customer.getEmail(), "Account", message.toString()); } 上面的例子可謂發(fā)送消息最差勁的方法之一。由于消息嵌入到了程序代碼之中,如果沒(méi)有程序員的幫助,其他人幾乎不可能對(duì)消息進(jìn)行編輯。同時(shí),即使對(duì)于專(zhuān)業(yè)的程序員,如果他不了解代碼,要進(jìn)行編輯也很困難。如果你預(yù)見(jiàn)了這些麻煩,把代碼寫(xiě)成下面這種形式: static public final String STR_HELLO="尊敬的先生/女士: "; static public final String STR_MESSAGE="您的帳戶余額是 "; static public final String STR_BEY="致禮! 某某裝飾品公司"; 如果說(shuō)上述代碼使得消息編輯更容易,那么這種幫助也不會(huì)很多。很難要求一個(gè)不搞程序設(shè)計(jì)的人理解static和final的含義。此外,如果要改變消息的結(jié)構(gòu),上面這種代碼也不夠靈活。例如,人們可能要求你在郵件消息中加入更多來(lái)自數(shù)據(jù)源的信息,這時(shí),你就得修改構(gòu)造郵件的代碼,或許還要添加更多的static final String對(duì)象。 模板簡(jiǎn)介從文本文件裝入消息文本可以解決部分問(wèn)題??但不能提供動(dòng)態(tài)內(nèi)容,而這對(duì)于系統(tǒng)來(lái)說(shuō)是很重要的。你需要有一種方法把動(dòng)態(tài)內(nèi)容插入到預(yù)先編寫(xiě)好的文本消息。但是,如果使用某種文本模板引擎,它就能夠幫助你完成所有復(fù)雜的工作。 模板引擎解決了把動(dòng)態(tài)內(nèi)容插入文本消息的問(wèn)題。使用模板引擎時(shí),我們不再把消息直接嵌入程序,而是創(chuàng)建一個(gè)包含文本內(nèi)容的簡(jiǎn)單文本文件,稱為“文本模板”。模板引擎解析文本模板,借助一些簡(jiǎn)單的模板指令,把動(dòng)態(tài)內(nèi)容插入模板輸出結(jié)果。 我選擇的模板引擎是Jakarta Project的Velocity,但你可以任意選擇其他許多模板引擎之一。Velocity和WebMacro或許是當(dāng)前功能最豐富、最受歡迎的兩個(gè)引擎,而且兩者都按照源代碼開(kāi)放協(xié)議免費(fèi)提供。雖然我在本文例子中使用Velocity,你可以方便地把這些例子移植到不同的模板引擎,只需遵照目標(biāo)引擎的語(yǔ)法即可。我們來(lái)看看用Velocity完成的email程序例子。要編譯和運(yùn)行修改后的程序,你必須下載Velocity并把它加入到classpath。如果要讓email部分也能正常運(yùn)行,你還需要JavaMail。 for (int i=0; i in ”。#foreach指令迭代list,把list中的每個(gè)元素放入item參數(shù),然后解析#foreach塊內(nèi)的內(nèi)容。對(duì)于 list內(nèi)的每個(gè)元素,#foreach塊的內(nèi)容都會(huì)重復(fù)解析一次。從效果上看,它相當(dāng)于告訴模板引擎說(shuō):“把list中的每一個(gè)元素依次放入item變量,每次放入一個(gè)元素,輸出一次#foreach塊的內(nèi)容”。 MVC設(shè)計(jì)模型在看下一個(gè)例子之前,請(qǐng)回顧一下前面我們所討論的內(nèi)容。使用模板引擎最大的好處在于,它分離了代碼(或程序邏輯)和表現(xiàn)(輸出)。由于這種分離,你可以修改程序邏輯而不必?fù)?dān)心郵件消息本身;類(lèi)似地,你(或公關(guān)部門(mén)的職員)可以在不重新編譯程序的情況下,重新編寫(xiě)郵件消息。 實(shí)際上,我們分離了系統(tǒng)的數(shù)據(jù)模式(Data Model,即提供數(shù)據(jù)的類(lèi))、控制器(Controller,即郵件程序)以及視圖(View,即模板)。這種三層體系稱為Model-View- Controller模型(MVC)。如果遵從MVC模型,代碼分成三個(gè)截然不同的層,簡(jiǎn)化了軟件開(kāi)發(fā)過(guò)程中所有相關(guān)人員的工作(MVC的出現(xiàn)已經(jīng)有一段時(shí)間,參見(jiàn)本文最后的“參考資源”了解更多信息)。 結(jié)合模板引擎使用的數(shù)據(jù)模式可以是任何Java對(duì)象,最好是使用Java Collection Framework的對(duì)象??刂破髦灰私饽0宓沫h(huán)境(如VelocityContext),一般這種環(huán)境都很容易使用。一些關(guān)系數(shù)據(jù)庫(kù)的“對(duì)象-關(guān)系” 映射工具能夠和模板引擎很好地協(xié)同,簡(jiǎn)化JDBC操作;對(duì)于EJB,情形也類(lèi)似。 模板引擎與MVC中視圖這一部分的關(guān)系更為密切。模板語(yǔ)言的功能很豐富、強(qiáng)大,足以處理所有必需的視圖功能,同時(shí)它往往很簡(jiǎn)單,不熟悉編程的人也可以使用它。模板語(yǔ)言不僅使得設(shè)計(jì)者從過(guò)于復(fù)雜的編程環(huán)境中解脫出來(lái),而且它保護(hù)了系統(tǒng),避免了有意或無(wú)意帶來(lái)危險(xiǎn)的代碼。例如,模板的編寫(xiě)者不可能編寫(xiě)出導(dǎo)致無(wú)限循環(huán)的代碼,或侵占大量?jī)?nèi)存的代碼。不要輕估這些安全機(jī)制的價(jià)值;大多數(shù)模板編寫(xiě)者不懂得編程,從長(zhǎng)遠(yuǎn)來(lái)看,避免他們接觸復(fù)雜的編程環(huán)境相當(dāng)于節(jié)省了你自己的時(shí)間。 許多模板引擎的用戶相信,在采用模板引擎的方案中,控制器部分和視圖部分的明確分離,再加上模板引擎固有的安全機(jī)制,使得模板引擎足以成為其他內(nèi)容發(fā)布系統(tǒng)(比如JSP)的替代方案。因此,Java模板引擎最常見(jiàn)的用途是替代JSP也就不足為奇了。 HTML處理由于人們總是看重模板引擎用來(lái)替換JSP的作用,有時(shí)他們會(huì)忘記模板還有更廣泛的用途。到目前為止,模板引擎最常見(jiàn)的用途是處理HTML Web內(nèi)容。但我還用模板引擎生成過(guò)SQL、email、XML甚至Java源代碼。在這里我只能涉及模板的部分應(yīng)用,但你可以從本文最后的參考資源找到更多的例子。 我將在下面的HTML例子中使用前面email例子的數(shù)據(jù)模式。這個(gè)HTML頁(yè)面是一個(gè)假想的企業(yè)Intranet頁(yè)面,它顯示出客戶帳戶的詳細(xì)信息。本例中的控制器類(lèi)是一個(gè)Java Servlet,視圖部分則包含一個(gè)HTML模板。下面的代碼顯示了Servlet類(lèi)中最主要的代碼。為使這個(gè)例子更具有代表性,我從頭開(kāi)始手工編寫(xiě)這個(gè) Servlet。然而,一般情況下,模板會(huì)提供一些Servlet工具,幫助用戶減輕一些編寫(xiě)代碼的負(fù)擔(dān)。 // 裝入模板 Template template = Velocity.getTemplate("html.vm"); // 創(chuàng)建環(huán)境 VelocityContext context = new VelocityContext(); context.put ("customers",Customer.getCustomers());// 解析模板,輸出應(yīng)答ServletOutputStream output = response.getOutputStream();Writer writer = new OutputStreamWriter (output);template.merge(context, writer);writer.flush(); 這個(gè)例子也沒(méi)有什么令人驚異的地方。和前面的例子一樣,我只是把必需的對(duì)象加入到VelocityContext,然后輸出解析模板的結(jié)果。但是請(qǐng)注意,在前面的例子中,我只把一個(gè)Customer加入到VelocityContext,這里加入到VelocityContext的卻是一組 Customer對(duì)象。我可以用#foreach指令迭代訪問(wèn)所有的Customer對(duì)象。下面是相應(yīng)的HTML模板:

客戶報(bào)告

#foreach ($customer in $customers)

$customer.CustName

#foreach ($transaction in $customer.Transactions) <ul id="yqumg"><sup id="yqumg"></sup></ul>
$transaction.Date
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI