当前位置:天才代写 > tutorial > JAVA 教程 > 用Java措施生成文本的捷径

用Java措施生成文本的捷径

2017-11-13 08:00 星期一 所属: JAVA 教程 浏览:355

副标题#e#

本文配套源码

大大都措施都需要输出一些文本,好比邮件动静、HTML文件或节制台输出。可是,计较机本质上只能处理惩罚二进制数据,措施员必需让软件来生成可领略的文本。在这篇文章中,我要先容的是在生成和输出文本时,为何利用模板引擎可以或许节减时间。你将相识模板的利益,如何针对差异的景象建设高效的模板。和System.println说再见!

固然措施员可以很轻松地编写出输出文字信息的代码(因为这究竟是从Hello World典型学到的第一件工作),但凡是而言,措施员不是写作或组织文字信息(如邮件)的最尤物选。因此,我们经常让市场部分或公关部分去做那些工作。但遗憾的是,纵然对付最普通的邮件,编写者也经常依赖措施输出来完成任务。无论是对付邮件编写者照旧措施员,这种相助方法都很容易带来误解和造成失误。

请看一个例子:一个Java措施从某个数据源收集一些客户信息,通过email给公司的每一个客户发送帐户余额信息。下面是完成这个任务的Java措施(完整的示例措施代码可以从本文最后下载):

for (int i=0; i
{
Customer customer = (Customer)customers.get(i);
StringBuffer message = new StringBuffer();
message.append ("尊敬的先生/密斯:");
message.append (customer.getCustName());
message.append ("\n");
message.append ("\n");
message.append ("您的帐户余额是 ");
message.append (customer.getAccountTotal());
message.append ("\n");
message.append ("\n");
message.append ("致礼!");
message.append ("\n");
message.append ("某某装饰品公司");
// 发送email
mm.sendMail (customer.getFirstName(), customer.getEmail(),
"Account", message.toString());
}

上面的例子可谓发送动静最差劲的要领之一。由于动静嵌入到了措施代码之中,假如没有措施员的辅佐,其他人险些不行能对动静举办编辑。同时,纵然对付专业的措施员,假如他不相识代码,要举办编辑也很坚苦。假如你预见了这些贫苦,把代码写成下面这种形式:

static public final String STR_HELLO="尊敬的先生/密斯:";
static public final String STR_MESSAGE="您的帐户余额是 ";
static public final String STR_BEY="致礼!\n某某装饰品公司";

假如说上述代码使得动静编辑更容易,那么这种辅佐也不会许多。很难要求一个不搞措施设计的人领略static和final的寄义。另外,假如要改改观静的布局,上面这种代码也不足机动。譬喻,人们大概要求你在邮件动静中插手更多来自数据源的信息,这时,你就得修改结构邮件的代码,或者还要添加更多的static final String工具。


#p#副标题#e#

模板简介

从文本文件装入动静文本可以办理部门问题——但不能提供动态内容,而这对付系统来说是很重要的。你需要有一种要领把动态内容插入到预先编写好的文本动静。可是,假如利用某种文本模板引擎,它就可以或许辅佐你完成所有巨大的事情。

模板引擎办理了把动态内容插入文本动静的问题。利用模板引擎时,我们不再把动静直接嵌入措施,而是建设一个包括文本内容的简朴文本文件,称为“文本模板”。模板引擎理会文本模板,借助一些简朴的模板指令,把动态内容插入模板输出功效。

我选择的模板引擎是Jakarta Project的Velocity,但你可以任意选择其他很多模板引擎之一。Velocity和WebMacro或者是当前成果最富厚、最受接待的两个引擎,并且两者都凭据源代码开放协议免费提供。固然我在本文例子中利用Velocity,你可以利便地把这些例子移植到差异的模板引擎,只需遵照方针引擎的语法即可。

我们来看看用Velocity完成的email措施例子。要编译和运行修改后的措施,你必需下载Velocity并把它插手到classpath。假如要让email部门也能正常运行,你还需要JavaMail。

for (int i=0; i<customers.size(); i++)
{
Customer customer = (Customer)customers.get(i);
// 建设一个情况,并插手所有的工具
VelocityContext context = new VelocityContext();
context.put ("CustName",customer.getCustName());
context.put ("total", new Double (customer.getAccountTotal()));
context.put ("customer", customer );
// 理会模板,生成功效字符串
StringWriter message = new StringWriter();
template.merge(context, message);
// 发送email
mm.sendMail (customer.getFirstName(), customer.getEmail(),
"Account", message.toString());
}

#p#分页标题#e#

首先,你应该领略上面的Java源代码。这里我们不再象第一个例子那样生成文本,上面的代码引用一个称为“Velocity模板”的文本文件,然后把功效发送给收件人。Velocity模板可以是任何文本文件,但一般它包括一些用来插入动态内容的指令。

和VelocityContext相关的部门是上述代码中最值得留意的处所。VelocityContext提供了Java措施和Velocity文本模板之间的毗连,而Velocity文本模板可以由其他人来编写。在模板中,所有插手到VelocityContext的工具都可以通过put()要领第一个参数指定的名字会见。为相识其事情进程,请看下面的模板文件:

尊敬的先生/密斯:$CustName
您的帐户余额是 $total
致礼!
某某装饰品公司

Velocity引擎读取模板文件时,它直接输出文件中所有的文本,但以$字符开头的除外。$标记标识着一个位置,在模板的输出功效中,工具的值应该插入到$标记所指示的位置。譬喻,Java代码中有一个context.put ("CustName",customer.getCustName())语句,当Velocity模板引擎理会并输出模板的功效时,模板中所有呈现$CustName的处所都将插入客户的名字;即,被插手到VelocityContext的工具的toString()要领返回值将替代Velocity变量(模板中以$开头的变量)。

模板引擎中最强大、利用最频繁的成果之一是它通过内建的映像(Reflection)引擎查找工具信息的本领。这个映像引擎答允用一种利便的Java“.”雷同的操纵符,提取任意插手到VelocityContext的工具的任何公用要领的值,或工具的任意数据成员。映像引擎还带来了别的一个改造:快速引用JavaBean的属性。利用JavaBean属性的时候,我们可以忽略get要领和括号(欲知具体信息,请参考模板引擎的说明文档)。请看下面这个模板的例子。由于在前面的Java代码示例中,我把Customer工具插手到了VelocityContext,所以我可以把模板改写成下面这种形式:

尊敬的先生/密斯:$customer.CustName
您的帐户余额是 $customer.AccountTotal
致礼!
某某装饰品公司

#p#副标题#e#

除了替换变量之外,象Velocity和WebMacro这类高级引擎还能做其他很多工作。它们有用来较量和迭代的内建指令(尽量较量和迭代成果是两个模板引擎之间的配合点,但它们的语法差别很大,不能完全兼容。在选择模板引擎可能改换模板引擎时,务必留意这一点)。

举一个例子。十二月份,你的老板想要向所有的客户发一个圣诞节问候的email。你可以把这个动静插手到模板,今后再删除它。但这样的话,你得在新年那一天上班事情,以便删除圣诞问候动静。

一种更好的步伐是指示模板何时显示圣诞问候动静。为此,你首先要把当前的月份插手到VelocityContext:

int month = (new GregorianCalendar()).get(Calendar.MONTH);
// 把month值加1,因为它从0开始计较
context.put ("month", new Integer(month+1) );

此刻,你只需在模板中举办较量:

尊敬的先生/密斯:$customer.CustName
您的帐户余额是 $customer.AccountTotal
致礼!
某某装饰品公司
#if ($month == 12)
祝您和您的家人圣诞节快乐!
#end

#if指令的浸染很清楚:对一个逻辑表达式举办测试,从而抉择是否在模板输出功效中包括该指令块内的内容。除了简朴的便是较量之外,你还可以执行更巨大的较量,但这方面的成果都与特定的模板引擎密切关联,所以这里我不再先容。

迭代指令和#if指令一样简朴。模板引擎支持迭代Java Collections Framework的任意实现,包罗Array、List和Iterator。对付JDK 1.2可能更高版本,Java的Vector和ArrayList都实现了List接口,因此它们也适合在模板引擎的迭代指令中利用。

假设我们此刻不想输出帐户余额,而是想通过迭代遍历帐户的生意业务记录,输出具体的报表。Customer工具的getTransactions()要领(拜见下载包中完整的示例代码)返回一个List工具,List工具包括零个可能多个Transaction工具。由于List属于Java Collections Framework的一部门,我们可以用#foreach指令迭代其内容。我们不消担忧如何定型工具的范例——映像引擎会为我们完成这个任务。从下面这个例子中,我们可以看出迭代的事情进程:

尊敬的先生/密斯:$customer.CustName
#foreach ($transaction in $customer.Transactions)
$transaction.Description $transaction.Amount
#end
您的帐户余额是 $customer.AccountTotal
致礼!
某某装饰品公司

#p#分页标题#e#

#foreach指令的一般名目是“#foreach <item> in <list>”。#foreach指令迭代list,把list中的每个元素放入item参数,然后理会#foreach块内的内容。对付list内的每个元素,#foreach块的内容城市反复理会一次。从结果上看,它相当于汇报模板引擎说:“把list中的每一个元素依次放入item变量,每次放入一个元素,输出一次#foreach块的内容”。

MVC设计模子

在看下一个例子之前,请回首一下前面我们所接头的内容。利用模板引擎最大的长处在于,它疏散了代码(或措施逻辑)和表示(输出)。由于这种疏散,你可以修改措施逻辑而不必担忧邮件动静自己;雷同地,你(或公关部分的职员)可以在不从头编译措施的环境下,从头编写邮件动静。

实际上,我们疏散了系统的数据模式(Data Model,即提供数据的类)、节制器(Controller,即邮件措施)以及视图(View,即模板)。这种三层体系称为Model-View-Controller模子(MVC)。假如遵从MVC模子,代码分成三个截然差异的层,简化了软件开拓进程中所有相关人员的事情(MVC的呈现已经有一段时间,拜见本文最后的“参考资源”相识更多信息)。

团结模板引擎利用的数据模式可以是任何Java工具,最好是利用Java Collection Framework的工具。节制器只要相识模板的情况(如VelocityContext),一般这种情况都很容易利用。一些干系数据库的“工具-干系”映射东西可以或许和模板引擎很好地协同,简化JDBC操纵;对付EJB,景象也雷同。

模板引擎与MVC中视图这一部门的干系更为密切。模板语言的成果很富厚、强大,足以处理惩罚所有必须的视图成果,同时它往往很简朴,不熟悉编程的人也可以利用它。模板语言不只使得设计者从过于巨大的编程情况中摆脱出来,并且它掩护了系统,制止了有意或无意带来危险的代码。譬喻,模板的编写者不行能编写出导致无限轮回的代码,或侵占大量内存的代码。不要轻估这些安详机制的代价;大大都模板编写者不分明编程,从久远来看,制止他们打仗巨大的编程情况相当于节减了你本身的时间。

很多模板引擎的用户相信,在回收模板引擎的方案中,节制器部门和视图部门的明晰疏散,再加上模板引擎固有的安详机制,使得模板引擎足以成为其他内容宣布系统(好比JSP)的替代方案。因此,Java模板引擎最常见的用途是替代JSP也就不敷为奇了。

#p#副标题#e#

HTML处理惩罚

由于人们老是垂青模板引擎用来替换JSP的浸染,有时他们会健忘模板尚有更遍及的用途。到今朝为止,模板引擎最常见的用途是处理惩罚HTML Web内容。但我还用模板引擎生成过SQL、email、XML甚至Java源代码。在这里我只能涉及模板的部门应用,但你可以从本文最后的参考资源找到更多的例子。

我将在下面的HTML例子中利用前面email例子的数据模式。这个HTML页面是一个假想的企业Intranet页面,它显示出客户帐户的具体信息。本例中的节制器类是一个Java Servlet,视图部门则包括一个HTML模板。下面的代码显示了Servlet类中最主要的代码。为使这个例子更具有代表性,我从新开始手工编写这个Servlet。然而,一般环境下,模板会提供一些Servlet东西,辅佐用户减轻一些编写代码的承担。

// 装入模板
Template template = Velocity.getTemplate("html.vm");
// 建设情况
VelocityContext context = new VelocityContext();
context.put ("customers",Customer.getCustomers());
// 理会模板,输出应答
ServletOutputStream output = response.getOutputStream();
Writer writer = new OutputStreamWriter (output);
template.merge(context, writer);
writer.flush();

这个例子也没有什么令人惊异的处所。和前面的例子一样,我只是把必须的工具插手到VelocityContext,然后输出理会模板的功效。可是请留意,在前面的例子中,我只把一个Customer插手到VelocityContext,这里插手到VelocityContext的却是一组Customer工具。我可以用#foreach指令迭代会见所有的Customer工具。下面是相应的HTML模板:

<html>
<body>
<h1>客户陈诉</h1>
#foreach ($customer in $customers)
<h2>$customer.CustName<h2>
<table>
#foreach ($transaction in $customer.Transactions)
<tr>
<td width="200">
$transaction.Date
</td>
<td width="150">
$transaction.Description
</td>
<td width="100">
$transaction.Amount
</td>
</tr>
#end
</tr>
<td></td>
<td></td>
<td><b>$customer.AccountTotal</b></td>
<tr>
</table>
#end
</body>
</html>

#p#分页标题#e#

假如你正在筹划一个工程,这个工程的需求远远高出几个HTML模板,请思量浩瀚以模板为基本的框架之一。这些框架不只为生成HTML提供了模板引擎所带来的便利,并且提供很多实用东西,好比数据库毗连池和安详。两个常见的例子是Turbine和Melati,它们都和Velocity以及WebMacro兼容,都是免费且源代码开放的产物。

机能和设置

对付大大都措施来说,模板的速度看来已经足够快;但对付大容量的Web网站,你大概要当真地思量一下机能问题。在机能方面,模板引擎最大的特点在于模板缓冲。在模板缓冲机制的浸染下,模板不再是每次呈现请求的时候从磁盘读取,而是以最抱负的方法在内存中生存息争析。在开拓期间,模板缓冲凡是处于禁用状态,因为这时请求数量较少,并且要求对页面的修改当即发生结果。陈设完毕之后,模板一般不再改变,机能就成了优先思量的问题。因此,这时你应该启用模板缓冲成果。

对付大大都模板引擎,你可以通过应用一个配置选项或编辑Java属性文件利便地启用模板缓冲成果。在Velocity中,你可以通过Properties工具初始化模板。至于Properties工具的建设要领,你既可以手工建设,就象我前面所做的那样;可能也可以从属性文件装入。在实际应用中,后者也许是较为抱负的要领。

Properties props = new Properties();
props.setProperty( "file.resource.loader.cache", "true" );
props.setProperty( "file.resource.loader.modificationCheckInterval", "3600" );
Velocity.init (props);

通过file.resource.loader.cache属性可以把缓冲配置成true或false,而file.resource.loader.modificationCheckInterval属性配置的是查抄文件是否改变的隔断秒数。在这里我无法具体先容所有的属性,请参考模板引擎的文档相识更多信息。

■ 竣事语

免费的高级模板引擎使我们可以或许把模板成果插手到险些所有的Java应用。这些模板引擎为措施员提供了易用的东西,为模板编写者提供了简朴的模板语言,使得开拓者更有信心编写出高质量的代码。

模板疏散了措施代码和应用的表示部门,极大处所便了措施员和内容建造者的事情。模板把措施员从殽杂了大量文本信息的混乱代码中解放出来;使得建造文本内容的人无需面临措施逻辑,就可以轻松地编写和修改内容。

模板清楚地疏散了措施逻辑和文本表示代码,从而也为设计更好的MVC系统提供了利便。因此,模板为替换其他内容宣布系统(好比JSP)提供了一种有吸引力的方案,因为它可以或许在不增加巨大性的环境下,改造应用的整体设计。

 

    关键字:

天才代写-代写联系方式