Velocity模板引擎介绍
整理下Velocity使用方法,整理比较详细用例
1 Velocity基础语法
1.1 用户和开发人员参考文档
http://velocity.apache.org/engine/releases/velocity-1.7/developer-guide.html
1.2 注释
1.行级注释##
2.多行注释#* *#
1.3 变量定义
使用$开头的字符串是变量定义,例如$var1, $var2,
1.4 赋值
使用#set为变量赋值,例如
Java代码
- #set($var1 = 100)
- #set($str="foobar")
- #set($var2 = $var1)
- $var2 ##显示100
1. #set指令需要使用小括号将赋值语句括起来
2. #set语句后面不要加“;”,否则;将解析到页面上
3. #set是行级指令,不需要使用#end
1.5 {}含义
假如有一个Velocity变量,例如$abc, 那么$abcdef这种串如何表达它的含义,即变量$abc的值连接def,默认Velocity会认为$abcdef是一个变量,此时需要使用${abc}def来表达它的含义。
1.6 算术运算
1. 运算符: + - * / %
2. 使用#set语句执行算术运算操作
Java代码
- #set($a = 5)
- #set($b = 4)
- #set($c = 3)
- #set($d = 2)
- #set($e = 7)
- #set($a= $a+$b*$c/$d - 6%$e) ##5+4*3/2-6%7=5
- "Result:" $a
1.7 关系运算
> >= == <= <
1.8 逻辑运算
&& || !
1.9 条件判断
Java代码
- #set($var1 = 20)
- #if($va1 >= 100)
- $var1 is greater than or equals 100
- #elseif($va1 >= 50)
- $var1 is betwen [50, 100)
- #elseif($var1 >= 0)
- $var1 is between [0,50)
- #else
- $var1 is negative
- #end
1. #if是条件判断语句,#if/#else, #if/#elseif/#else 是if/else条件判断语句
2. if/elseif使用括号括起来
3. #if是块级指令,因此使用#end显示指定块级指令的结束
1.10 循环语句
Java代码
- #set($array = [1, "Two", 3,"Four"])
- #foreach($i in $array)
- <li>
- The $velocityCount element in the array is $i
- </li>
- #end
1. 数组定义类似于Javascript,用中括号[]括起来,以逗号分隔
2. $velocityCount是Velocity内置属性,用于指示当前循环的次数,从1开始计算,即第一次循环,它的值是1
3. #foreach in语句用于表示循环,
4. #foreach语句也是块级语句,需要使用#end来指明语句的结束
1.11 $!的含义
$!var1的含义是如果变量var1存在,则取其值,否则取空,即不显示,它等价于如下语句
Java代码
- #set($var1 = 100)
- $!var2 ##show nothing
- $!var1 ##show 100
- #if($var1)
- $var1
- #end
- #if($var2)
- #var2
- #end
1.12 #include指令
#include可以在vm中指定静态文件,这跟JSP的include标签的含义一样,例如
#include("staticHTML.html"),这个staticHTML.html
#include指令默认从classpath开始寻找文件??目前不确定!
1.13 Velocity资源加载器
在#include指令一节说到了include的文件到什么位置进行加载,这个位置与velocity资源加载的配置有关,常用的加载位置包括 webapp资源加载器,文件路径资源加载器,还有类路径记载器,在velocity.properties中,添加如下的配置项表示webapp资源加 载器,项目对于web项目的根开始算起
Java代码
- resource.loader=webapp
- webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
- #relative to the web context, under the same parent directory with WEB-INF
- #that is, vm and WEB-INF are sibling folders
- webapp.resource.loader.path=/vm
其中的webapp是资源加载器的名称,/vm是web应用的根下面的vm目录,也就是说,vm目录和WEB-INF目录是平级的
Velocity是一个基于java的模板引擎。它允许任何人仅仅简单的使用模板语言来引用由java代码定义的对象。
当Velocity应用于web开发时,界面设计人员可以和java程序开发人员同步开发一个遵循MVC架构的web站点,也就是说,页面设计人员 可以只 关注页面的显示效果,而由java程序开发人员关注业务逻辑编码。Velocity将java代码从web页面中分离出来,这样为web站点的长期维护提 供了便利,同时也为我们在JSP和PHP之外又提供了一种可选的方案。
Velocity基本语法和使用:
1. "#"用来标识Velocity的脚本语句。
如:#set、#if 、#else、#foreach、#end、#include、#parse、#macro等。
2. "$"用来标识一个对象(或理解为PHP的变量)
如:、
user等。
3. "{}"用来明确标识Velocity变量,和普通模版字符串区分开来;
如:${user}‘s age 可以显示为 riqi's age。
4. "!"强制把不存在的变量显示为空白。
如:,假如对象为空,则模版中不显示该变量;如果缺少,则显示
msg字符串,这是我们不想要的结果。
5. 变量的定义和赋值。不需要指定变量的类型,类似弱类型语言PHP可以随意指定,在赋值后自动判定变量的类型,如:
#set($username="riqi") ##设置用户名
#set($age=26) ##设置年龄
6. 数组循环:
#foreach ($user in $users)
$!{user} $!{velocityCount} <br />
#end
可以是、或者,提供了得到循环次数的值:
velocityCount。
7. 语句注释:
单行注释:## 单行注释代码
多行注释:#* 多行注释代码 *#
8. 模版支持关系和逻辑操作符运算,如:&&、||、! 等
9. 宏定义:#macro ,类似PHP声明一个函数,其中有函数名称和参数列表。先定义再调用。
10. 终止命令:#stop,类似PHP的exit(); 停止执行模板引擎并返回。
11. 引入公共模版文件:#include与#parse,它们的差异是:
(1) 与#include不同的是,#parse只能指定单个对象。而#include可以有多个
如果您需要引入多个文件,可以用逗号分隔就行:
#include ("one.gif", "two.txt", "three.htm" )
在括号内可以是文件名,但是更多的时候是使用变量的:
#include ( “greetings.txt”, $seasonalstock )
(2) #include被引入文件的内容将不会通过模板引擎解析;
而#parse引入的文件内容Velocity将解析其中的velocity语法并移交给模板,意思就是说相当与把引入的文件copy到文件中。
#parse是可以递归调用的。
12. 转义字符'\'.
这个和其它语言没有差异,假如:那么,表示输出
user字符串,\\$user表示输出\riqi。
13. Velocity内置了一部分java对象 如:、
response、$session等,在vm模版里可以直接调用。
------------------------------------------------------------------------------------
细节整理:
1. Velocity判断某个变量是否为空的方式:
1 |
#if($!变量名)……#else……#end |
或者:
1 |
#if("" == $!varName)……#else……#end |
2 Velocity与Java互操作
Velocity出现的目的用于简化基于MVC的web应用开发,用于替代JSP标签技术,那么Velocity如何访问Java代码.本篇继续以Velocity三http://bit1129.iteye.com/blog/2106142中的例子为基础,
2.1 POJO
Java代码
- package com.tom.servlets;
- public class User {
- private String name;
- private String passwd;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPasswd() {
- return passwd;
- }
- public void setPasswd(String passwd) {
- this.passwd = passwd;
- }
- }
2.2 Service
Java代码
- package com.tom.servlets;
- public class UserService {
- public User get(String userId) {
- User user = new User();
- user.setName("tom");
- user.setPasswd("tom_pwd");
- return user;
- }
- public User get(Long userId) {
- User user = new User();
- user.setName("Jack");
- user.setPasswd("Jack");
- return user;
- }
- public void save() {//用于测试,vm是否可以调用无参数的方法
- System.out.println("save is called");
- }
- }
2.3 Servlet代码
Java代码
- package com.tom.servlets;
- import org.apache.velocity.Template;
- import org.apache.velocity.context.Context;
- import org.apache.velocity.tools.view.VelocityViewServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class TestVelocityViewServlet extends VelocityViewServlet {
- @Override
- protected Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctx) {
- UserService userService = new UserService();
- ctx.put("userService" , userService);//把userService对象设置到Context中
- return getTemplate("obj.vm");
- }
- }
2.4 vm代码
Html代码
- <!--obj.vm-->
- <html>
- <body>
- <p>$userService</p> ##call userService's toString method
- #set($user = $userService.get(0)) ##When call the java method on its object, only string typed parameters can be accepted
- <p>$user.name</p> ##print #$user.name as it is, because $user can't be resolved
- <p>$user.getName()</p> ##Equivalent with $user.name
- #set($user = $userService.get("0"))
- <p>$user.name</p> ##print $$user.name as it is, because $user can't be resolved
- <p>$user.getName()</p> ##Equivalent with $user.name
- <p>$user.save()</p> ##$user.save can't be resolved,so vm can't resolve method that takes no parameter
- </body>
- </html>
2.5 运行结果
com.tom.servlets.UserService@48b4721b
$user.name
$user.getName()
tom
tom
$user.save()
2.6 总结
1.可以通过Velocity将Java的对象注入到Context中,这样在vm中可以获得这个注入的Java对象,例子中调用了这个Java对象的toString方法
2.在vm中,仅仅能调用Java对象的带有String类型参数的方法,这是非性常巨大的局限,因为在vm中,没法像在JSP中通过<%%>创建Java对象,然后把它作为参数调用Java的方法
3.对于setter和getter,可以直接使用属性进行方法,例如$user.getName和$user.name是等价的,不管User类是否定义了name属性(比如把User类中的属性name改名为xname,getName和setName方法名不变)
4.$user.save()不能正确解析,也就是说,vm只能调用Java对象带String类型参数的方法(POJO的get方法除外)
3 脱离servlet使用velocity
Java代码
- package com.tom.velocity;
- import java.io.InputStream;
- import java.io.StringWriter;
- import java.util.Properties;
- import org.apache.velocity.Template;
- import org.apache.velocity.VelocityContext;
- import org.apache.velocity.app.VelocityEngine;
- public class HelloVelocity {
- public static void main(String[] args) throws Exception {
- //实例化并初始化Velocity模板引擎
- VelocityEngine ve = new VelocityEngine();
- Properties p = new Properties();
- InputStream in = HelloVelocity.class.getClassLoader().getResourceAsStream("velocity.properties");
- p.load(in);
- ve.init(p);
- //从指定目录下加载自定的vm文件
- Template t = ve.getTemplate("vm/hello.vm");
- //创建Velocity上下文环境,用于在vm和Java传值
- VelocityContext context = new VelocityContext();
- context.put("name", "tom");
- context.put("job", "code-farmer");
- //将模板序列化为字符串文档,进行打印
- StringWriter writer = new StringWriter();
- t.merge(context, writer);
- //将模板引擎解析的结果打印输出
- System.out.println(writer.toString());
- //输出
- /*
- <p>name: tom</p>
- <p>job: code-farmer</p>
- */
- }
- }
3.1 velocity.properties文件
存放在classpath根目录下,内容:
Java代码
- resource.loader=class
- #Why ClasspathResourceLoader search the vm in the root directory of classpath
- #This means, <class.resource.loader.path> doesn't take effect
- class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
- class.resource.loader.path=vm
3.2 hello.vm文件
存放在{classpath根目录}/vm目录下。
Java代码
- <p>name: $name</p>
- <p>job: $job</p>
3.3 java中使用详细实例
3.3.1 模板内容
<?xml version="1.0" encoding="utf-8"?>
<T24 xmlns="http://www.temenos.com/T24/OFSML/130" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.temenos.com/T24/OFSML/130 ofsml13.xsd">
<ofsmlHeader>
<requestId>$_utils.uuid()$ofsRequest.getTxCode()</requestId>
<correlationId/>
</ofsmlHeader>
<serviceRequest>
<securityContext>
<userName>$ofsRequest.getName()</userName>
<password>$ofsRequest.getPassword()</password>
<company>$ofsRequest.getCompany()</company>
</securityContext>
<ofsStandardEnquiry name="$ofsRequest.getEnquiryName()">
#set($struct = $ofsRequest.getStruct)
#foreach ($item in $ofsRequest.getMessageData())
#if($_tools.isEmpty($struct) || $_tools.isNotEmpty($struct.get($item.getName())))
<selectionCriteria operand="$item.getOperator()">
<fieldName>$item.getName()</fieldName>
<value>#foreach($vItem in $item.getValue())$vItem #end</value>
</selectionCriteria>
#end
#end
</ofsStandardEnquiry>
</serviceRequest>
</T24>
3.3.2 重点部分java代码
// 组合请求消息报文对象
OFSEnquiryRequest ofsRequest = new OFSEnquiryRequest();
ofsRequest.setHeader(msgType + SPLIT_ROW + txCode);
ofsRequest.setName(name);
ofsRequest.setPassword(password);
ofsRequest.setCompany(company);
ofsRequest.setEnquiryName((String) msgHead.get("enquiryName"));
ofsRequest.setStruct(struct);
ofsRequest.setTxCode(txCode);
if (null != msgBody && msgBody.containsKey("messageData")) {
ofsRequest.setMessageData((List<OFSEnquiryReqItem>) msgBody.get("messageData"));
}
// 根据模板组合请求xml内容
VelocityContext ctx = new VelocityContext();
ctx.put("_tools", Tools.getInstance());
ctx.put("_utils", VelocityUtil.getInstance());
ctx.put("ofsRequest", ofsRequest);
String ofsmlEqyXml = "";
try {
// 变量REQ中保存了上面的模板内容
ofsmlEqyXml = VelocityHelper.getText(REQ, ctx);
} catch (Exception e) {
}
4.Velocity模板优缺点
对于大部分的应用来说,使用 FreeMarker 比 Velocity 更简单,因为 Velocity 还必须编写一些自定义的toolbox类以及一遍遍重复的编写一些比较通用的模版代码,因此也就丧失了刚开始开发时更多的宝贵时间。另外使用工具类和变通的方法在模版引擎中似乎不是一个非常有效的做法。同时,Velocity 的做法使得在Velocity的模版中大量的跟 Java 对象进行交互,这违反了简单的原则,尽管你也可以将代码转入控制器中实现。当然,如果你像使用 Velocity 一样来使用 FreeMarker ,那么 FreeMarker 也可以跟 Velocity 一样简单。
Velocity 一个优于 FreeMarker 的地方在于它有很广泛的第三方支持以及一个非常庞大的用户社区,你可以通过这个社区获得到很多的帮助,相反的 FreeMarker 在这方面要差很多。当然,也有越来越多的第三方软件开始在支持 FreeMarker 。
velocity性能比freemarker好很多,应该是最好的,又看到说性能超过jsp。
Velocity模板引擎介绍的更多相关文章
- Velocity 模板引擎介绍
一.变量 1. 变量定义 #set($name =“velocity”) 2. 变量的使用 在模板文件中使用$name 或者${name} 来使用定义的变量.推荐使用${name} 这种格式,因为在模 ...
- Velocity模板引擎语法
Velocity 模板引擎介绍 Velocity是一个基于java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java ...
- 使用 Velocity 模板引擎快速生成代码(zhuan)
http://www.ibm.com/developerworks/cn/java/j-lo-velocity1/ ****************************************** ...
- 使用Velocity 模板引擎快速生成代码
Velocity 模板引擎介绍 在现今的软件开发过程中,软件开发人员将更多的精力投入在了重复的相似劳动中.特别是在如今特别流行的MVC架构模式中,软件各个层次的功能更加独立,同时代码的相似度也更加高. ...
- 【转载】Velocity模板引擎的介绍和基本的模板语言语法使用
原文地址http://www.itzhai.com/the-introduction-of-the-velocity-template-engine-template-language-syntax- ...
- velocity模板引擎学习(4)-在standalone的java application中使用velocity及velocity-tools
通常velocity是配合spring mvc之类的框架在web中使用,但velocity本身其实对运行环境没有过多的限制,在单独的java application中也可以独立使用,下面演示了利用ve ...
- velocity模板引擎学习(3)-异常处理
按上回继续,前面写过一篇Spring MVC下的异常处理.及Spring MVC下的ajax异常处理,今天看下换成velocity模板引擎后,如何处理异常页面: 一.404错误.500错误 <e ...
- Velocity模板引擎入门
类似于PHP中的Smarty,Velocity是一个基于Java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java代 ...
- 转 如何使用velocity模板引擎开发网站
基于 Java 的网站开发,很多人都采用 JSP 作为前端网页制作的技术,尤其在是国内.这种技术通常有一些问题,我试想一下我们是怎样开发网站的,通常有几种方法: 1:功能确定后,由美工设计网页的UI( ...
随机推荐
- ibatis 动态列查询问题解决
http://hi.baidu.com/java513/blog/item/ace7c516c400390d4a90a7c8.html 这个问题是因为你查询的sql的列是变化的,但是ibati ...
- 转 iOS:NSAttributedString
NSAttributedString: http://blog.csdn.net/kmyhy/article/details/8895638 CTFramesetterSuggestFrameSize ...
- [原创]Linux实现服务延迟启动
在开机启动服务的时候,服务之间有依赖关系,必须在某个服务完全启动后才能启动其他的服务.在这种情况下,就需要用到服务延迟启动的功能.在开机时,延迟几分钟再启动.具体步骤如下:1.写一个实现延时启动的脚本 ...
- WCF信道工厂Channel Factory
ChannelFactory<TChannel> 类 一个创建不同类型通道的工厂,客户端使用这些通道将消息发送到不同配置的服务终结点. 命名空间: System.ServiceModel ...
- Centos 7 启动错误:XFS_WANT_CORRUPTED_GOTO 修复
参考源 如果出现以下报错 [sda] Assuming drive cache: write through Internal error xfs XFS_WANT_CORRUPTED_GOTO at ...
- js获取object类型所有的键值对
万物皆对象,而对象完全可以用键值对来表示,所以,在js中,也是通过键值对来表示对象的,在开发中,我在修改的时候,知道属性值可以直接用点.符号来获取值,但是写common.js的时候,发现这个属性名称是 ...
- Prime pair connection (Project Euler 134)
题目大意: 对于连续的质数$p1$, $p2$, 满足$5 <= p1 <= 1000000$ 求出最小的整数$S$, 它以 $p1$结尾并且能够被$p2$整除. 求$S$的和. 思路: ...
- centos7 virtualbox使用internal network 内网模式
1)打开对应虚拟机的Settings,点开Network, 2)Adapter1如果已经选了挂到Bridged Adapter,则点开Adapter2, 3)选择挂到 Internal Network ...
- cookie小细节
设置cookie时,不像设置session,可以马上生效,它的生效时间是下一次请求页面.
- ios 集成阿里百川的坑-【SDK初始化-iOS】读取身份图片AppKey失败
最简易方法调用淘宝app: 引用文件 #import <AlibcTradeSDK/AlibcTradeSDK.h> AlibcWebViewController* view = [[Al ...