Velocity的学习1

Velocity

是一个基于Java的的模板引擎,经过特定的语法,速度能够获取在的Java语言中定义的对象,从而实现界面和Java的代码的真正分离,这意味着可使用Velocity替代JSP的开发模式了(实际上笔者所在的公司正在开发基于Cayenne的Velocity产品)。javascript

Cayenne O / R.php

Cayenne是一个OpenSource Java对象关系套件,提供运行时O / R框架和Swing GUI映射/部署工具。Velocity用做GUI或Ant任务中基于模板的类生成的引擎。css

 

 

这使得前端开发人员能够和Java程序开发人员同步开发一个遵循MVC架构的网站点,在实际应用中,Velocity还能够应用于不少其余的场景。html

1. Velocity的介绍

Velocity是一个基于Java的的模板引擎,其提供了一个上下文容器,在Java的代码里面咱们能够往容器中存值(MVC的模型中,咱们往ActionForm里面进行set值,JSP页面自动映射form的数据),而后在虚拟机文件中使用特定的语法获取,这是Velocity基本的用法,其与JSP,freemarker并称为三大视图展示技术,相对于JSP而言,Velocity对先后端的分离更加完全:在VM文件中不容许出现的java代码,而JSP文件中却能够。前端

2. Velocty的基本用法java

在这里咱们以一个HelloVelocity做为速度的入门实例。在首先apache官网下载velocity的最新发布包,新建普通的java项目,引入其中的速度-1.7.jar和LIB文件夹下的全部罐包便可。而后分为以下两步:python

2.1初始化速度引擎

编写HelloVelocity.java文件以下:jquery

public static void main(String[] args) { // 初始化模板引擎  VelocityEngine ve = new VelocityEngine();  ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); ve.init(); // 获取模板文件  Template t = ve.getTemplate("hellovelocity.vm"); // 设置变量  VelocityContext ctx = new VelocityContext(); ctx.put("name", "Velocity"); List list = new ArrayList(); list.add("1"); list.add("2");  ctx.put("list", list); // 输出 StringWriter sw = new StringWriter(); t.merge(ctx,sw); System.out.println(sw.toString()); } 

首先,咱们在代码中初始化了VelocityEngine这个模板引擎,对其设置参数进行初始化,指定使用ClasspathResourceLoader来加载虚拟机文件。web

而后咱们就能够往VelocityContext这个Velocity容器中存放对象了,在虚拟机文件中咱们能够取出这些变量,从而进行模板输出。apache

2.2编写hellovelocity.vm文件

其中,虚拟机文件放在类路径目录下便可,类加载器会进行加载
hellovelocity.vm文件以下:

#set($greet = 'hello') $greet $name #foreach($i in $list) $i #end 

控制台输出以下:

hello Velocity
1
2

2.3 Velocity的基本语法

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

3.1变量

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

#set(${!name} = "velocity") #set(${!foo} = $bar) #set($foo =“hello”) #set($foo.name = $bar.name) #set($foo.name = $bar.getName($arg)) #set($foo = 123) #set($foo = [“foo”,$bar]) 

须要注意,上面代码中$!{}的写法,使用$ vari获取变量时,若是变量不存在,Velocity引擎会将其原样输出,经过使用$!{}的形式能够将不存在的变量变成空白输出。

3.2循环

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

#foreach($item in $list) $item $velocityCount #end 

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

velocity.properties

 

counter.name = velocityCount

counter.initial.value = 1

 

3.3条件控制语法

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

#if(condition) ...dosonmething... #elseif(condition) ...dosomething... #else ...dosomething... #end 

3.4宏

Velocity中也有宏的概念,能够将其做为函数来理解,使用#macro声明宏

## 声明宏 #macro(sayHello $name) hello $name #end ## 使用宏 #sayHello("NICK") 

3.5解析和包含指令

Velocity中能够经过解析

parse

或者包括指令include引入外部VM文件,可是两者存在区别:包括指令会将外部文件原样输出,而解析指令会先对其进行解析再输出(即对外部文件中的VM语法解析)

#parse("header.vm") #include("footer.vm") 

4.在web项目中使用Velocity

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

经过继承或直接使用VelocityViewServlet,能够在管理的vm文件中得到请求,会话与应用程序对象,也能够直接获取在这几个域对象中保存的值,获取的顺序与EL表达式获取的顺序相似:
${request}- - > ${session}- > ${application}
好比${testArr}获取testArr属性,速度会在速度的上下文中寻找没找到在请求域中找,没找到在会话中找。

下面将经过实例的方式讲解如何在网络项目中使用速度
首先引入速度的工具依赖及其的相关的jar包,而后分为以下4步:

4.1继承VelocityViewServlet

经过继承的VelocityViewServlet重写的handleRequest方法,能够自定义转发规则

public class MyVelocityViewServlet extends VelocityViewServlet { @Override protected Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctx) { // 往Context容器存放变量 ctx.put("fullName","lixiaolin"); // 也能够往request域中存值 request.setAttribute("anotherName","xlli"); // forward到指定模板 return getTemplate("test.vm"); } } 

4.2配置web.xml

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

<servlet> <servlet-name>MyVelocityServlet</servlet-name> <servlet-class>com.lxl.velocity.MyVelocityViewServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyVelocityServlet</servlet-name> <url-pattern>/servlet/myVelocityServlet</url-pattern> </servlet-mapping> 

4.3编写vm文件

VM文件是做为JSP的替代来展现给用户,在VM文件中能够得到在上下文域或请求等域中存放的值。默认状况下,会在资源根路径下搜索VM文件,因此直接将VM放在根路径下便可(也能够经过配置velocity.properties指定加载路径)
以下:

#set($greet = "hello")
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <p>$!{greet} $!{fullName}</p> <p>my another name is $!{anotherName}</p> </body> </html> 

4.4配置velocity.properties

经过配置velocity.properties文件,能够自定义虚拟机文件加载方式,指定编码等。固然,也能够不配置velocity.properties,使用缺省的值便可。

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

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

5.使用VelocityLayoutServlet

在网络站点开发的过程当中,常常会碰到几个页面的布局大体相同,好比引用相同的头部和尾部,左侧边栏相同等,在使用JSP开发时咱们能够将头部等公共文件抽离出来,而后在实际页面中引入.Velocity也提供了相似的功能,而且该功能更增强大。

apache提供了VelocityLayoutServlet来实现页面布局,它是的VelocityViewServlet的子类,经过使用VelocityLayoutServlet能够简化Velocity下页面布局开发,可使当向前到一个VM页面时,把该页面做为一个已有页面布局的一部分总体显示出来,好比访问资料页面,可以自动把头,尾部显示出来

Velocity的工具包中已经包含了这个类,其使用分为以下几步:

5.1配置velocity.properties

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

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

5.2布局母版vm文件

布局layout.vm文件是全部要展现的虚拟机文件的母版,以下所示:

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>${page_title}</title> #if($!{CSS}) #foreach($_css in ${CSS}) <link type="text/css" rel="stylesheet" href="${ContextPath}/$_css"> #end #end </head> <body> <div class="header"> #parse("/templates/layout/header.vm") </div> <div class="container"> <div class="sub"> #parse($sub) </div> <div class="main"> $screen_content </div> </div> #if($!JS) #foreach($_js in $JS) <script type="text/javascript" src="${CntextPath}/${_js}"> #end #end </body> </html> 

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

5.3编写转发的vm文件

#set($layout = "/templates/layout/layout.vm") #set($CSS = ["scripts/css/index.css"]) #set($JS = ["scripts/js/jquery-1.11.3.js"]) #set($page_title = "主页") #set($sub = "/templates/sub.vm") <div id="main-show"> this is main-show </div> 

5.4继承VelocityLayoutServlet

public class MyLayoutServlet extends VelocityLayoutServlet { @Override protected void doRequest(HttpServletRequest request, HttpServletResponse response) throws IOException { // 设置通用的变量 request.setAttribute("Request", request); request.setAttribute("ContextPath", request.getContextPath()); request.setAttribute("BasePath", request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath()); long runtime = System.currentTimeMillis(); super.doRequest(request, response); if (request.getAttribute("close_comment") == null) { Date cur_time = Calendar.getInstance(request.getLocale()).getTime(); PrintWriter pw = response.getWriter(); pw.print("\r\n<!-- Generated by VelocityApp Server("); pw.print(cur_time); pw.print(") Cost "); pw.print(cur_time.getTime() - runtime); pw.print(" ms -->"); pw.flush(); pw.close(); } } } 

6.附录及参考文献

参考文献

相关文章
相关标签/搜索