http://blog.csdn.net/qq_25237663/article/details/52262532

****************************************************************

Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取在java语言中定义的对象,从而实现界面和java代码的真正分离,这意味着可以使用velocity替代jsp的开发模式了(实际上笔者所在的公司已经这么做了)。这使得前端开发人员可以和 Java 程序开发人员同步开发一个遵循 MVC 架构的 web 站点,在实际应用中,velocity还可以应用于很多其他的场景.

1. Velocity的介绍

Velocity是一个基于Java的模板引擎,其提供了一个Context容器,在java代码里面我们可以往容器中存值,然后在vm文件中使用特定的语法获取,这是velocity基本的用法,其与jsp、freemarker并称为三大视图展现技术,相对于jsp而言,velocity对前后端的分离更加彻底:在vm文件中不允许出现java代码,而jsp文件中却可以.

作为一个模块引擎,除了作为前后端分离的MVC展现层,Velocity还有一些其他用途,比如源代码生成、自动email和转换xml等,具体的用法可以参考这篇文章.

2. Velocty的基本用法

在这里我们以一个HelloVelocity作为Velocity的入门实例.首先在官网下载velocity的最新发布包,新建普通java项目,引入其中的velocity-1.7.jar和lib文件夹下的所有jar包即可. 然后分为如下两步:

2.1 初始化Velocity引擎

编写HelloVelocity.java文件如下:

  1. public static void main(String[] args) {
  2. // 初始化模板引擎
  3. VelocityEngine ve = new VelocityEngine();
  4. ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
  5. ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
  6. ve.init();
  7. // 获取模板文件
  8. Template t = ve.getTemplate("hellovelocity.vm");
  9. // 设置变量
  10. VelocityContext ctx = new VelocityContext();
  11. ctx.put("name", "Velocity");
  12. List list = new ArrayList();
  13. list.add("1");
  14. list.add("2");
  15. ctx.put("list", list);
  16. // 输出
  17. StringWriter sw = new StringWriter();
  18. t.merge(ctx,sw);
  19. System.out.println(sw.toString());
  20. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

首先,我们在代码中初始化了VelocityEngine这个模板引擎,对其设置参数进行初始化,指定使用ClasspathResourceLoader来加载vm文件。然后我们就可以往VelocityContext这个Velocity容器中存放对象了,在vm文件中我们可以取出这些变量,从而进行模板输出.

2.2 编写hellovelocity.vm文件

其中,vm文件放在classpath目录下即可,类加载器会进行加载
hellovelocity.vm文件如下:

  1. #set($greet = 'hello')
  2. $greet $name
  3. #foreach($i in $list)
  4. $i
  5. #end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

控制台输出如下:

  1. hello Velocity
  2. 1
  3. 2
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

2.3 Velocity的基本语法

本文中只简单的介绍几个Velocity的基本语法,具体可以参考这篇文章

3.1 变量

在Velocity中也有变量的概念,使用$符声明变量,可以声明变量也可以对变量进行赋值(变量是弱类型的)。另外还可以使用$取出在VelocityContext容器中存放的值

  1. #set(${!name} = "velocity")
  2. #set(${!foo} = $bar)
  3. #set($foo =“hello”)
  4. #set($foo.name = $bar.name)
  5. #set($foo.name = $bar.getName($arg))
  6. #set($foo = 123)
  7. #set($foo = [“foo”,$bar])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

需要注意,上面代码中 $!{}的写法,使用$vari获取变量时,如果变量不存在,Velocity引擎会将其原样输出,通过使用\$!{}的形式可以将不存在的变量变成空白输出.

3.2 循环

在Velocity中可以使用循环语法遍历集合,语法结构如下:

  1. #foreach($item in $list)
  2. $item
  3. $velocityCount
  4. #end
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

其中,$item代表遍历的每一项,velocityCount是Velocity提供的用来记录当前循环次数的计数器,默认从1开始计数,可以在velocity.properties文件中修改其初始值

3.3 条件控制语法

在Velocity中可以使用条件语法对流程进行控制

  1. #if(condition)
  2. ...dosonmething...
  3. #elseif(condition)
  4. ...dosomething...
  5. #else
  6. ...dosomething...
  7. #end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.4 宏

在Velocity中也有宏的概念,可以将其作为函数来理解,使用#macro声明宏

  1. ## 声明宏
  2. #macro(sayHello $name)
  3. hello $name
  4. #end
  5. ## 使用宏
  6. #sayHello("NICK")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.5 parse和include指令

在Velocity中可以通过parse或者include指令引入外部vm文件,但是二者存在区别:include指令会将外部文件原样输出,而parse指令会先对其进行解析再输出(即对外部文件中的vm语法解析)

  1. #parse("header.vm")
  2. #include("footer.vm")
  • 1
  • 2
  • 1
  • 2

4. 在web项目中使用Velocity

velocity只是一个模板引擎,在web项目中使用Velocity还得添加一个HTTP框架来处理请求和转发,apache提供了velocity-tools,其提供了VelocityViewServlet,也可继承VelocityViewServlet,从而实现自己的HTTP框架
一般都是继承VelocityViewServlet,重写handleRequest方法,在其中存入公共的参数.

通过继承或直接使用VelocityViewServlet,可以在管理的vm文件中获得request、session与application对象,也可以直接获取在这几个域对象中保存的值,获取的顺序与EL表达式获取的顺序类似:
${request} –> ${session} –> ${application}
比如${testArr}获取testArr属性,velocity会在velocity的context中寻找。没找到在request域中找,没找到在session中找.

下面将通过实例的方式讲解如何在web项目中使用Velocity
首先引入velocity-tools及其依赖的相关jar包,然后分为如下4步:

4.1 继承VelocityViewServlet

通过继承VelocityViewServlet重写handleRequest方法,可以自定义转发规则

  1. public class MyVelocityViewServlet extends VelocityViewServlet {
  2. @Override
  3. protected Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctx) {
  4. // 往Context容器存放变量
  5. ctx.put("fullName","lixiaolin");
  6. // 也可以往request域中存值
  7. request.setAttribute("anotherName","xlli");
  8. // forward到指定模板
  9. return getTemplate("test.vm");
  10. }
  11. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4.2 配置web.xml

对自定义的VelocityViewServlet配置就像配置普通的Servlet一样,如下:

  1. <servlet>
  2. <servlet-name>MyVelocityServlet</servlet-name>
  3. <servlet-class>com.lxl.velocity.MyVelocityViewServlet</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>MyVelocityServlet</servlet-name>
  7. <url-pattern>/servlet/myVelocityServlet</url-pattern>
  8. </servlet-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4.3 编写vm文件

vm文件是作为jsp的替代来展示给用户,在vm文件中可以获得在Context域或request等域中存放的值。默认情况下,会在资源根路径下搜索vm文件,所以直接将vm放在根路径下即可(也可以通过配置velocity.properties指定加载路径)
如下:

  1. #set($greet = "hello")
  2. <!doctype html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Document</title>
  7. </head>
  8. <body>
  9. <p>$!{greet} $!{fullName}</p>
  10. <p>my another name is $!{anotherName}</p>
  11. </body>
  12. </html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4.4 配置velocity.properties

通过配置velocity.properties文件,可以自定义vm文件加载方式,指定编码等。当然,也可以不配置velocity.properties,使用缺省的值即可.

  1. ## 设置模板文件加载器,webapp从应用根目录加载
  2. resource.loader = webapp
  3. webapp.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader
  4. ## 模板路径,根目录下的vm文件夹
  5. webapp.resource.loader.path = /vm
  6. ## 设置编码
  7. input.encoding = UTF-8
  8. output.encoding = UTF-8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

最后,在浏览器中访问http://localhost:8080/VelocityApp/servlet/myVelocityServlet即可

5. 使用VelocityLayoutServlet

在web站点开发的过程中,经常会碰到几个页面的布局大致相同,比如引用相同的头部和尾部、左侧边栏相同等,在使用jsp开发时我们可以将头部等公共文件抽离出来,然后在实际页面中引入。Velocity也提供了类似的功能,并且该功能更加强大.

apache提供了VelocityLayoutServlet来实现页面布局,它是VelocityViewServlet的子类,通过使用VelocityLayoutServlet可以简化velocity下页面布局开发,可以使当forward到一个vm页面时,把该页面作为一个已有页面布局的一部分整体显示出来,比如访问资料页面,能够自动把头、尾部显示出来

velocity-tools包中已经包含了这个类,其使用分为如下几步:

5.1 配置velocity.properties

在/WEB-INF/路径下配置velocity.properties文件,指定模板布局文件的位置

  1. input.encoding=UTF-8
  2. output.encoding=UTF-8
  3. ## 定义加载器
  4. resource.loader=webapp
  5. webapp.resource.loader.cache=false
  6. ## 布局文件夹位置
  7. tools.view.servlet.layout.directory = /templates/layout
  8. ## 定义默认布局文件
  9. tools.view.servlet.layout.default.template = layout.vm
  10. ## 错误模板文件
  11. tools.view.servlet.error.template = err.vm
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

5.2 布局母版vm文件

布局layout.vm文件是所有要展示的vm文件的母版,如下所示:

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>${page_title}</title>
  6. #if($!{CSS})
  7. #foreach($_css in ${CSS})
  8. <link type="text/css" rel="stylesheet" href="${ContextPath}/$_css">
  9. #end
  10. #end
  11. </head>
  12. <body>
  13. <div class="header">
  14. #parse("/templates/layout/header.vm")
  15. </div>
  16. <div class="container">
  17. <div class="sub">
  18. #parse($sub)
  19. </div>
  20. <div class="main">
  21. $screen_content
  22. </div>
  23. </div>
  24. #if($!JS)
  25. #foreach($_js in $JS)
  26. <script type="text/javascript" src="${CntextPath}/${_js}">
  27. #end
  28. #end
  29. </body>
  30. </html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

其中,有个特殊的变量 screen_content,这是Velocity内置的变量,代表将要转发的页面

5.3 编写转发的vm文件

  1. #set($layout = "/templates/layout/layout.vm")
  2. #set($CSS = ["scripts/css/index.css"])
  3. #set($JS = ["scripts/js/jquery-1.11.3.js"])
  4. #set($page_title = "主页")
  5. #set($sub = "/templates/sub.vm")
  6. <div id="main-show">
  7. this is main-show
  8. </div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5.4 继承VelocityLayoutServlet

  1. public class MyLayoutServlet extends VelocityLayoutServlet {
  2. @Override
  3. protected void doRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
  4. // 设置通用的变量
  5. request.setAttribute("Request", request);
  6. request.setAttribute("ContextPath", request.getContextPath());
  7. request.setAttribute("BasePath", request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath());
  8. long runtime = System.currentTimeMillis();
  9. super.doRequest(request, response);
  10. if (request.getAttribute("close_comment") == null) {
  11. Date cur_time = Calendar.getInstance(request.getLocale()).getTime();
  12. PrintWriter pw = response.getWriter();
  13. pw.print("\r\n<!-- Generated by VelocityApp Server(");
  14. pw.print(cur_time);
  15. pw.print(") Cost ");
  16. pw.print(cur_time.getTime() - runtime);
  17. pw.print(" ms -->");
  18. pw.flush();
  19. pw.close();
  20. }
  21. }
  22. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

6. 附录及参考文献

参考文献
* 使用 Velocity 模板引擎快速生成代码
* Velocity教程

本文中的完整代码可在github上下载.
你可以通过jslinxiaoli@foxmail.com联系我.
欢迎在github或者知乎上关注我 ^_^.
也可以访问个人网站: https://jslixiaolin.github.io

 

Velocity教程 (zhuan)的更多相关文章

  1. Velocity教程【转】

    原文:http://blog.csdn.net/qq_25237663/article/details/52262532 Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity ...

  2. Velocity教程-脚本语法详解(转)

    Velocity是一个基于java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象. 当Veloci ...

  3. Velocity教程

    Velocity 语法(转) 一.基本语法 1."#"用来标识Velocity的脚本语句,包括#set.#if .#else.#end.#foreach.#end.#iinclud ...

  4. 最小的 Velocity 教程

    工作以后,我越来越能体会到80/20法则的强大. 这是一个不可否认的事实,常用 20% 的技术可以解决工作中 80% 的场景. 所以我希望能介绍给你 Velocity 技术 20%,帮助你胜任 80% ...

  5. Activiti初学者教程 (zhuan)

    http://blog.csdn.NET/bluejoe2000/article/details/39521405 ****************************************** ...

  6. Virtualbox虚拟机安装CentOS6.5图文详细教程(zhuan)

    http://www.2cto.com/os/201407/318477.html ************************************************* 什么是Virtu ...

  7. velocity 教程

    1,<title> $!{product.name} - $!{title} $!{about.title} - $!{title} $!{news.title} - $!{title} ...

  8. linux远程管理器 - xshell和xftp使用教程(zhuan)

    准备好连接linux服务器的工具,推荐用xshell和xftp. xshell 是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET ...

  9. velocity 知识点

    velocity 教程: http://www.51gjie.com/javaweb/126 velocity 语法 语法 说明 关键字以#开头 定义数组 ['aaa','bbb'] 变量以$开头 把 ...

随机推荐

  1. C#常用日期格式处理转换[C#日期格式转换大全

    DateTime dt = DateTime.Now; Label1.Text = dt.ToString();//2005-11-5 13:21:25 Label2.Text = dt.ToFile ...

  2. java 导入自定义类

    eclipse导入很容易,昨天上课学了一下用记事本写java,导入自定义类,这就麻烦了. 代码贴一下,方便操作: package tom.jiafei; public class SquareEqua ...

  3. randperm函数

    randperm功能是随机打乱一个数字序列. 语法格式: y = torch.randperm(n) y是把1到n这些数随机打乱得到的一个数字序列. th> torch.randperm() [ ...

  4. tensorflow安装

    Ubuntu安装tensorflow先安装python-dev,再安装tensorflow就好了$ sudo apt-get install python-dev$ pip install https ...

  5. CentOS 安装Redis

    redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcached类似,但很大程度补偿了memcached的不足,它支持存储的value类型相对更多,包括strin ...

  6. Codeforces Round #373 (Div. 2) B

    Description Anatoly lives in the university dorm as many other students do. As you know, cockroaches ...

  7. 2016年12月11日 星期日 --出埃及记 Exodus 21:6

    2016年12月11日 星期日 --出埃及记 Exodus 21:6 then his master must take him before the judges. He shall take hi ...

  8. shell脚本之lnmp的搭建

    !/bin/bash #this script is source packages installed lnmp .xmal yum -y install wget #"========= ...

  9. number_format

    number_format — 以千位分隔符方式格式化一个数字 说明 string number_format ( float $number [, int $decimals = 0 ] ) str ...

  10. MSM8974 fastboot烧写软件

    fastboot烧写是在aboot阶段做的,所以空板没有完整烧写aboot及其boot sequence前的image是没法使用fastboot的.在手机开机状态下,执行:        adb re ...