用Java程序生成文本的捷径

本人至善

本人至善

2016-02-19 14:58

清醒时做事,糊涂时读书,大怒时睡觉,无聊时关注图老师为大家准备的精彩内容。下面为大家推荐用Java程序生成文本的捷径,无聊中的都看过来。

  大多数程序都需要输出一些文本,比如邮件消息、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对象。

  模板简介

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

  从文本文件装入消息文本可以解决部分问题但不能提供动态内容,而这对于系统来说是很重要的。你需要有一种方法把动态内容插入到预先编写好的文本消息。但是,如果使用某种文本模板引擎,它就能够帮助你完成所有复杂的工作。

  模板引擎解决了把动态内容插入文本消息的问题。使用模板引擎时,我们不再把消息直接嵌入程序,而是创建一个包含文本内容的简单文本文件,称为文本模板。模板引擎解析文本模板,借助一些简单的模板指令,把动态内容插入模板输出结果。

  我选择的模板引擎是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());
 }

本文示例代码或素材下载

  首先,你应该理解上面的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
致礼!
某某装饰品公司

  除了替换变量之外,象Velocity和WebMacro这类高级引擎还能做其他许多事情。它们有用来比较和迭代的内建指令(尽管比较和迭代功能是两个模板引擎之间的共同点,但它们的语法差异很大,不能完全兼容。在选择模板引擎或者更换模板引擎时,务必注意这一点)。

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

  一种更好的办法是指示模板何时显示圣诞问候消息。为此,你首先要把当前的月份加入到VelocityContext:

  

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

  现在,你只需在模板中进行比较:

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

  

尊敬的先生/女士: $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
致礼!
某某装饰品公司

本文示例代码或素材下载

展开更多 50%)
分享

猜你喜欢

用Java程序生成文本的捷径

编程语言 网络编程
用Java程序生成文本的捷径

用ASP随机生成文件名的函数

ASP
用ASP随机生成文件名的函数

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Java学习的捷径

Java JAVA基础
Java学习的捷径

从Java应用程序动态生成PDF文件

编程语言 网络编程
从Java应用程序动态生成PDF文件

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

利用 Java Web Start发布你用java程序

编程语言 网络编程
利用  Java Web Start发布你用java程序

随机生成文件名的函数

ASP
随机生成文件名的函数

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

怎样把相册照片做成大头贴?

怎样把相册照片做成大头贴?

HTML教程认识optgroup元素

HTML教程认识optgroup元素
下拉加载更多内容 ↓