学习一个新技术 我们首先要了解 这个东西是什么?能做什么?怎么用?在更深层次了解就是 原理是什么? 我们就先来执行第一步 Velocity 是什么。访问velocity官网进行快速了解。http://velocity.apache.org/

大致内容如下:

Velocity是一个基于Java的模板引擎。它允许任何人使用简单但功能强大的模板语言来引用Java代码中定义的对象。

当Velocity用于Web开发时,Web设计人员可以与Java程序员并行工作,根据模型 - 视图 - 控制器(MVC)模型开发Web站点,这意味着Web页面设计人员可以专注于创建看起来不错的站点,程序员可以专注于编写顶级代码。Velocity将Java代码与网页分离,使网站在其生命周期内更易于维护,并提供Java Server Pages(JSP)或PHP的可行替代方案。

Velocity的功能远远超出了网络领域; 例如,它可用于从模板生成SQL,PostScript和XML。它既可以用作生成源代码和报告的独立实用程序,也可以用作其他系统的集成组件。例如,Velocity为各种Web框架提供模板服务,使它们能够通过视图引擎根据真正的MVC模型促进Web应用程序的开发。

接下来就是如何使用Velocity

我们可以查看寡官方的示例进行了解Velocity如何使用

http://velocity.apache.org/engine/1.7/develope

r-guide.html

http://velocity.apache.org/engine/1.7/user-guide.html

在使用之前我们先说明一下版本,我们公司目前使用的版本是 1.7 目前最新的版本是2.0 我们这里介绍的是1.7 版本。

开发工具:STS

JDK 1.8

在开始之前 我们先引入Velocity的插件。

JAVa模板 java模板引擎velocity_apache

JAVa模板 java模板引擎velocity_apache_02

JAVa模板 java模板引擎velocity_Velocity _03

JAVa模板 java模板引擎velocity_JAVa模板_04

1 veloctiy 环境搭建和hello word 示例
好了闲话不多说,上代码:

第一步 引入Velocity的依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>cn.lijunkui</groupId>
   <artifactId>velocitylearn</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>war</packaging>
   <dependencies>
       <dependency>
     <groupId>org.apache.velocity</groupId>
     <artifactId>velocity</artifactId>
     <version>1.7</version>
     </dependency>
     <dependency>
     <groupId>org.apache.velocity</groupId>
     <artifactId>velocity-tools</artifactId>
     <version>2.0</version>
     </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>4.12</version>
             <scope>test</scope>
         </dependency>
   </dependencies>
    <build>  
         <plugins> 
         <!-- 跳过test 编译 -->
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
                 <configuration>
                   <skip>true</skip>
                 </configuration>
               </plugin>
                  
             <plugin>  
                 <artifactId>maven-compiler-plugin</artifactId>  
                 <configuration>  
                     <source>1.8</source>  
                     <target>1.8</target>  
                      <webXml>WebRoot\WEB-INF\web.xml</webXml>
                     <!-- 指定jsp、js、css的路劲 --> 
                      <warSourceDirectory>WebRoot</warSourceDirectory>
                 </configuration>  
             </plugin>  
             <plugin>
             <artifactId>maven-war-plugin</artifactId>
             <configuration>
             <version>3.0</version>
                 <failOnMissingWebXml>false</failOnMissingWebXml>
             </configuration>
             </plugin>
         </plugins>      
         <finalName>velocitylearn</finalName>  
     </build>  
 </project>


来一个hello word velocity

JAVa模板 java模板引擎velocity_JAVa模板_05

1 普通初始化

模板放在src目录下

JAVa模板 java模板引擎velocity_ci_06

package cn.lijunkui.api;
  
 import java.io.PrintWriter;
  
 import org.apache.velocity.Template;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.Velocity;
 import org.apache.velocity.app.VelocityEngine;
 /**
  * Velocity 使用demo 示例
  * @author lijunkui
  *
  */
 public class VelocityDemo {
     
     public void initVecocity() {
          VelocityEngine ve=new VelocityEngine();
          //设置模板加载路径,这里设置的是class下  
          ve.setProperty(Velocity.RESOURCE_LOADER, "class");
          ve.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
             try {   
                 //进行初始化操作   
                 ve.init();   
                 //加载模板,设定模板编码
                 Template t=ve.getTemplate("cn/lijunkui/api/initVecocity.vm","gbk");
                 //设置初始化数据   
                 VelocityContext context = new VelocityContext();   
                 //设置输出   
                 PrintWriter writer = new PrintWriter("D:\\helloword.html");   
                 //将环境数据转化输出   
                 t.merge(context, writer);   
                 writer.close();   
             } catch (Exception e) {   
                 e.printStackTrace();   
             }  
     }
 }


编写vm的模板

<html>
 <title>Hello Velocity</title>
 <body>
 <H2> Welcome use Velocity</H2>
 </body>
 </html>

运行后会在 d盘生成一个名称为helloword.html 页面 如下图所示

JAVa模板 java模板引擎velocity_ci_07

2 采用properties方式进行初始化

JAVa模板 java模板引擎velocity_html_08

编写vm的模板:

<!DOCTYPE html>
 <html lang="en">
  
 <head>
     <meta charset="UTF-8"> </meta>
 <title>Hello Velocity</title>
 </head>
 <body>
     我的名字叫$name 年龄是$age;
 </body>
 </html>
Properties prop = new Properties();
         // 配置模版目录
         
         prop.put("file.resource.loader.path","D:\\workspace-sts-3.9.5.RELEASE\\velocitylearn\\src\\main\\resources\\template");
         prop.put("input.encoding", "UTF-8");// 输入编码
         prop.put("output.encoding", "UTF-8");//输出编码
         Velocity.init(prop);
         
         VelocityContext context = new VelocityContext();
         
         StringBuffer str = new StringBuffer();
         FileOutputStream outStream = null;
         OutputStreamWriter writer = null;
     
         File file = new File("D:/catalog");
         if (!file.exists()) {
           
           file.mkdirs();
         }
        
         Map<String,Object> map=new HashMap<String,Object>();
         map.put("name", "张三");
         map.put("age",34);
         Set<String> set = map.keySet();
         Iterator<String> it = set.iterator();
         
         while(it.hasNext()){
             String key = it.next();
             context.put(key,map.get(key));
         }
         
         
         Template template = Velocity.getTemplate("hellovelocity.vm");
         File destFile = new File("D:/catalog","studyCard.html");
         outStream = new FileOutputStream(destFile);
         writer = new OutputStreamWriter(outStream,"utf-8");
         BufferedWriter sw = new BufferedWriter(writer);
         template.merge(context, sw);
         sw.flush();
         sw.close();
         writer.close();
         outStream.close();
     }
  测试用例:
     @Test
     public void initByProp() throws IOException {
         demo.initByProp();
     }

JAVa模板 java模板引擎velocity_Velocity _09

2 velocity 基本语法及使用

2.1 注释

单行注释  ## 内容

多行注释 #* 内容 *#

文档注释 #**内容*#

2.2 #set 定义变量

将我们后台操纵velocity引擎进行封装

private void test(String templatePath, String htmlPath) {
          VelocityEngine ve=new VelocityEngine();
          //设置模板加载路径,这里设置的是class下  
          ve.setProperty(Velocity.RESOURCE_LOADER, "class");
          ve.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
             try {   
                 //进行初始化操作   
                 ve.init();   
                 //加载模板,设定模板编码
                 Template t=ve.getTemplate(templatePath,"utf-8");
                 //设置初始化数据   
                 VelocityContext context = new VelocityContext();   
                 //设置输出   
                 PrintWriter writer = new PrintWriter(htmlPath);   
                 //将环境数据转化输出   
                 t.merge(context, writer);   
                 writer.close();   
             } catch (Exception e) {   
                 e.printStackTrace();   
             }  
         
     }
     public void set() {
         String templatePath = "cn/lijunkui/api/set.vm";
         String htmlPath = "D:\\set.html";
         test(templatePath,htmlPath);
     }
     @Test
     public void set() {
         demo.set();
     }


模板内容如下:

#set($word="zhuoqianmingyue")
 ${word}#$word
  
 #set($surname="Lee")
 #set($name="junkui")
  
 #set($fullname="$surname $name")
 ${fullname}


测试结果:

JAVa模板 java模板引擎velocity_ci_10

2.3 条件语句

#if #elseif #else #end
模板内容:condition.vm
#set($number = 1)
  
 #if($number == 1)
     这个数是 1
 #elseif($number == 2)
     这个数是 2
 #else
      这个数是3
 #end
     /**
      *  条件语句
      */
     public void condition() {
         String templatePath = "cn/lijunkui/api/condition.vm";
         String htmlPath = "D:\\condition.html";
         test(templatePath,htmlPath);
     }
     @Test
     public void condition() {
         demo.condition();
     }


 测试结果:

JAVa模板 java模板引擎velocity_ci_11

2.4 #foreach 循环标签
模板内容:

#foreach ( $item in [1..5] )
     $item
 #end
                               
 -------------------------------
                               
 #set ( $arr = [0..1] )
 #foreach ( $x in $arr )
     $x
 #end
 -------------------------------    
 #set ( $arr2 = [0..1] )
 #set ( $k = 1 )
 #foreach ( $x in $arr2 )
     x:$x,k: $k
 #set($k = $k+1)
 #end
 -------------------------------
     public void foreach() {
         String templatePath = "cn/lijunkui/api/foreach.vm";
         String htmlPath = "D:\\foreach.html";
         test(templatePath,htmlPath);
     }


 测试用例:

 

@Test
     public void foreach() {
         demo.foreach();
     }

测试结果:

JAVa模板 java模板引擎velocity_JAVa模板_12

2.5 Velocity 中的宏
我个人理解为定义函数 这里要注意的是 宏不支持重载

#macro(html)
  
  <h2>这是一个宏</h2>
  
 #end
  
 #macro(htmlContent $content)
  <h2>$content</h2>
 #end
  
 #html()
  
 #htmlContent("有参数的宏")
     /**
      * 定义宏标签
      */
     public void macro() {
         String templatePath = "cn/lijunkui/api/macro.vm";
         String htmlPath = "D:\\macro.html";
         test(templatePath,htmlPath);
     }
     @Test
     public void macro() {
         demo.macro();
     }


测试结果: 

JAVa模板 java模板引擎velocity_apache_13

2.6 debug语法标签 #stop

停止执行模板引擎并返回,把它应用于debug是很有帮助的。


 


  1. stop前的内容
  2. #stop
  3. stop后的内容

/**      * debug stop      */     public void stop() {         String templatePath = "cn/lijunkui/api/stop.vm";         String htmlPath = "D:\\stop.html";         test(templatePath,htmlPath);     }       @Test     public void stop() {         demo.stop();     } 测试结果: 从测试结果中我们可以看出 stop 后面的内容并没有执行 4、"!"用来强制把不存在的变量显示为空白。 如当页面中包含$msg,如果msg对象有值,将显示msg的值,如果不存在msg对象同,则在页面中将显示$msg字符。这是我们不希望的,为了把不存 在的变量或变量值为null的对象显示为空白,则只需要在变量名前加一个“!”号即可。 模板内容:noexist.vm #set($word="zhuoqianmingyue") 存在的内容:${word}# 不存在的内容:${word1} 不存在的内容不显示:$!{word1} <br>---------------------------<br> #if($!{word1})     存在  #else    不存在 #end     /**      * noexist      */          public void noexist() {         String templatePath = "cn/lijunkui/api/noexist.vm";         String htmlPath = "D:\\noexist.html";         test(templatePath,htmlPath);     } 测试用例:      @Test     public void noexist() {         demo.noexist();     } 测试结果:    引入本地文件 #include 和 #parse #include : 可以引入多个文件 而 #parse 只能引入单个文件 #include :被引入文件的内容将不会通过模板引擎解析  #parse 引入的文件内容Velocity将解析其中的velocity语法并移交给模板


JAVa模板 java模板引擎velocity_Velocity _14

JAVa模板 java模板引擎velocity_html_15

JAVa模板 java模板引擎velocity_html_16

#include( "abc.txt","cde.txt" ) 
     public void include() {
         String templatePath = "cn/lijunkui/api/include.vm";
         String htmlPath = "D:\\include.html";
         test(templatePath,htmlPath);
     }
     @Test
     public void include() {
         demo.include();
     }

#parse 导入脚本

JAVa模板 java模板引擎velocity_ci_17

JAVa模板 java模板引擎velocity_html_18

JAVa模板 java模板引擎velocity_ci_19

public void parse() {
         String templatePath = "cn/lijunkui/api/parse.vm";
         String htmlPath = "D:\\parse.html";
         test(templatePath,htmlPath);
     }
     @Test
     public void parse() {
         demo.parse();
     }

JAVa模板 java模板引擎velocity_html_20


11 vm中调用类的方法

定义一个String工具类 将小写内容转换为大写

package cn.lijunkui.api;
  
 public class StringUtils {
     public static String toUpper(String word) {
         return word.toUpperCase();
     }
 }
 编写模板引擎初始化并将工具类的实例对象加载进模板的上下文中    public void initWihtFun(String templatePath, String htmlPath) {
          VelocityEngine ve=new VelocityEngine();
          //设置模板加载路径,这里设置的是class下  
          ve.setProperty(Velocity.RESOURCE_LOADER, "class");
          ve.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
          ve.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "D:\\workspace-sts-3.9.5.RELEASE\\velocitylearn\\target\\velocitylearn\\WEB-INF\\classes\\cn\\lijunkui\\api");      
          try {   
                 //进行初始化操作   
                 ve.init();   
                 //加载模板,设定模板编码
                 Template t=ve.getTemplate(templatePath,"utf-8");
                 //设置初始化数据   
                 VelocityContext context = new VelocityContext(); 
                 StringUtils stringUtils = new StringUtils();
                 context.put("stringUtils", stringUtils);
                 //设置输出   
                 PrintWriter writer = new PrintWriter(htmlPath);   
                 //将环境数据转化输出   
                 t.merge(context, writer);   
                 writer.close();   
             } catch (Exception e) {   
                 e.printStackTrace();   
             } 
     }

编写模板内容:

useFun.vm
#set($word="zhuoqianmingyue")
 $stringUtils.toUpper("abc")
 $stringUtils.toUpper(${word})


编写测试用例:

  

public void useFun() {
         String templatePath = "cn/lijunkui/api/useFun.vm";
         String htmlPath = "D:\\useFun.html";
         initWihtFun(templatePath,htmlPath);
     }
      @Test
     public void useFun() {
         demo.useFun();
     }


 测试结果

JAVa模板 java模板引擎velocity_Velocity _21

12. 数组访问

对数组的访问在Velocity中存在问题,因为Velocity只能访问对象的方法,而数组

又是一个特殊的Array,所以虽然数组可以进行循环列举,但却不能定位访问特定

位置的元素,如 strs[2],数组对固定位置元素的访问调用了Array的反射方法

get(Object array, int index),而Velocity没能提供这样的访问,所以数组要么改成

List等其他类容器的方式来包装,要么就通过公用Util类的方式来提供,传入数组

对象和要访问的位置参数,从而达到返回所需值的目的。