velocity_velocity语法 - CSDN
  • Velocity入门教程

    千次阅读 2018-04-09 23:01:42
    一、概述Velocity是一个基于java的模板引擎,用于页面静态化。当前主流的模板引擎有Velocity、Freemarker 、Thymeleaf。二、可存放字符串、对象、数组、List、Map、时间、条件判断、页面复赋值等(大括号可省略)①取...
    一、概述

    Velocity是一个基于java的模板引擎,用于页面静态化。当前主流的模板引擎有Velocity、Freemarker 、Thymeleaf。

    二、可存放字符串、对象、数组、List、Map、时间、条件判断、页面复赋值等(大括号可省略)
    ①取字符串:
    $!Hello
    ②取对象:
    $person.name
    ③取List集合
    #foreach($person in $persons)
    $person.id 和 $person.name
    #end
    ④取Map集合
    #foreach($map in $maps.entrySet())
    $index $map.getKey() 和 $map.getValue()
    #end
    ⑤条件判断
    #if($bool)
    成立
    #else
    不成立
    #end
    ⑥页面赋值
    #set($name="老张")
    ${name}
    ⑦页面引入
    #parse("/common/nav.vm")

    三、点击下载SpringMVC结合velocity的例子
    展开全文
  • Velocity常用语法

    千次阅读 2018-06-19 13:48:12
    用来标识Velocity的脚本语句,包括#set、#if 、#else、#end、#foreach、#end、#iinclude、#parse、#macro等;如:#if($info.imgs)<img src="$info.imgs" border=0>#else<img src=&...

    一、基本语法

    1、"#"用来标识Velocity的脚本语句,包括#set、#if 、#else、#end、#foreach、#end、#iinclude、#parse、#macro等;
    如:
        #if($info.imgs)
            <img src="$info.imgs" border=0>
        #else
            <img src="noPhoto.jpg">
        #end

    2、"$"用来标识一个对象(或理解为变量);
        如:$i、$msg、$TagUtil.options(...)等。

    3、"{}"用来明确标识Velocity变量;
        比如在页面中,页面中有一个$someonename,此时,Velocity将把someonename作为变量名,若我们程序是想在someone这个变量的后面紧接着显示name字符,则上面的标签应该改成${someone}name。

    4、"!"用来强制把不存在的变量显示为空白。
        如当页面中包含$msg,如果msg对象有值,将显示msg的值,如果不存在msg对象同,则在页面中将显示$msg字符。这是我们不希望的,为了把不存在的变量或变量值为null的对象显示为空白,则只需要在变量名前加一个“!”号即可。
        如:$!msg

       1、$!obj  直接返回对象结果。
       如:在html标签中显示java对象msg的值。<p>$!msg</p>
      在html标签中显示经过HtmlUtil对象处理过后的msg对象的值  <p>$!HtmlUtil.doSomething($!msg)</p>

      2、#if($!obj) #else #end 判断语句
       如:在EasyJWeb各种开源应用中,我们经常看到的用于弹出提示信息msg的例子。
       #if($msg)
           <script>
               alert('$!msg');
           </script>
       #end
    上面的脚本表示当对象msg对象存在时,输出<script>等后面的内容。

        3、#foreach( $info in $list) $info.someList #end  循环读取集合list中的对象,并作相应的处理。
       如:EasyJF开源论坛系统中论(0.3)坛首页显示热门主题的html界面模板脚本:
      #foreach( $info in $hotList1)
    <a href="/bbsdoc.ejf?easyJWebCommand=show&&cid=$!info.cid" target="_blank">$!info.title</a><br>
      #end
       上面的脚本表示循环遍历hotList1集合中的对象,并输出对象的相关内容。
      
    5、#macro(macroName)#end 脚本函数(宏)调用,不推荐在界面模板中大量使用。
       如:在使用EasyJWeb Tools快速生成的添删改查示例中,可以点击列表的标题栏进行升降排序显示,这是我们在EasyJWeb应用中经常看到的一个排序状态显示的模板内容。
       函数(宏)定义,一般放在最前面
       #macro(orderPic $type)
       #if ($orderField.equals($type))
       <img src="/images/ico/${orderType}.gif">
       #end
       #end
    具体的调用如:<font color="#FFFFFF">头衔#orderPic("title")</font>

    6、包含文件#inclue("模板文件名")或#parse("模板文件名")
      主要用于处理具有相同内容的页面,比如每个网站的顶部或尾部内容。
      使用方法,可以参考EasyJF开源Blog及EasyJF开源论坛中的应用!
      如:#parse("/blog/top.html")或#include("/blog/top.html")
      parse与include的区别在于,若包含的文件中有Velocity脚本标签,将会进一步解析,而include将原样显示。

    关于#set的使用
      在万不得已的时候,不要在页面视图自己声明Velocity脚本变量,也就是尽量少使用#set。有时候我们需要在页面中显示序号,而程序对象中又没有包含这个序号属性同,可以自己定义。如在一个循环体系中,如下所示:
      #set ($i=0)
      #foreach($info in $list)
      序号:$i
      #set($i=$i+1)

      #end


    二、Velocity脚本语法摘要


    1、声明:#set ($var=XXX)
      左边可以是以下的内容
      Variable reference
      String literal
      Property reference
      Method reference
      Number literal #set ($i=1)
      ArrayList #set ($arr=["yt1","t2"])

      算术运算符

    2、注释:

        (1)单行注释: ## xxxx

        (2)多行注释: #* xxxxxx

                                 xxxx *#

        (3)文档格式: #** xxxxx

                                xxx

                            @author striner *#

    3、变量 Variables
      以 "$" 开头,第一个字符必须为字母。character followed by a VTL Identifier. (a .. z or A .. Z).
      变量可以包含的字符有以下内容:
      alphabetic (a .. z, A .. Z)
      numeric (0 .. 9)
      hyphen ("-")

      underscore ("_")

    (1)变量的定义:

    #set($name = "hello") 说明:velocity中变量是弱类型的。

    当使用#set 指令时,括在双引号中的字面字符串将解析和重新解释,如下所示:

    #set($directoryRoot = "www" )

    #set($templateName = "index.vm" )

    #set(directoryRoot/$templateName" )

    $template

    输出将会是:www/index.vm

    注:在velocity中使用$2.5这样的货币标识是没有问题得的,因为velocity中的变量总是以一个大写或者小写的字母开始的。

    (2)变量规范的写法

        也可以写成:​$name。提倡用前面的写法。

        例如:你希望通过一个变量$vice来动态的组织一个字符串。

         Jack is a $vicemaniac.

        本来变量是现在却变成了vicemaniac,这样Veloctiy就不知道您到底要什么了。所以,应该使用规范的格式书写 : Jack is a ${vice}maniac现在Velocity知道变量是vice而不是maniac。

    注意:当引用属性的时候不能加{}

    (3)变量的赋值:

        $name="hello"

        赋值的左边必须是一个变量或者是属性引用。右边可以是下面六种类型之一:

        变量引用,字面字符串,属性引用,方法引用,字面数字,数组列表。

        下面的例子演示了上述的每种类型:

        #set( bill ) ## variable reference

        #set( $monkey.Friend = "monica" ) ## string

        #set( whitehouse.Leak ) ## property reference

        #set( spindoctor.weave($web) ) ## method reference

        #set( $monkey.Number = 123 ) ##number

        #set( my, "fault"] ) ## ArrayList

        注意:①如果上述例子中的右值是null, 则左值不会被赋值,也就是说会保留以前的值。

        ②velocity模板中未被定义的变量将被认为是一个字符串。例如:

        #set($foo = "gibbous") foo输出结果为:$moon = gibbous

        ③velocity模板中不会将reference解释为对象的实例变量。例如:$foo.Name将被解释为Foo对象的getName()方法,而不是Foo对象的Name实例变量。例如:

        data.getRequest().getServerName() 等同于{data.Request.ServerName}

    4、Properties
      $Identifier.Identifier
      $user.name
      hashtable user中的的name值.类似:user.get("name")

    5、Methods
      object user.getName() = $user.getName()

    6、Formal Reference Notation
      用{}把变量名跟字符串分开

      如
      #set ($user="csy"}
      ${user}name
      返回csyname

      $username
      $!username
      $与$!的区别
      当找不到username的时候,$username返回字符串"$username",而$!username返回空字符串""

    7、双引号 与 引号
      #set ($var="helo")
      test"$var" 返回testhello
      test'$var' 返回test'$var'
      可以通过设置 stringliterals.interpolate=false改变默认处理方式

    8、条件语句
      #if( $foo )
       <strong>Velocity!</strong>
      #end
      #if($foo)
      #elseif()
      #else
      #end
      当$foo为null或为Boolean对象的false值执行.

    9、逻辑运算符:== && || !

    10、循环语句#foreach($var in $arrays ) // 集合包含下面三种Vector, a Hashtable or an Array
         
      #foreach( $product in $allProducts )
       <li>$product</li>
      #end

      #foreach( $key in $allProducts.keySet() )
       <li>Key: $key -> Value: $allProducts.get($key)</li>
      #end

      #foreach( $customer in $customerList )
       <tr><td>$velocityCount</td><td>$customer.Name</td></tr>

      #end

    例子:

        #set($list = ["pine", "oak", "maple"])

        #foreach ($element in $list)

        $velocityCount

    This is $element.<br>

        #end

    输出的结果为:

    1 This is pine. 2 This is oak. 3 This is maple.

    每次循环中的一个值都会赋给element变量。 可以是一个、或者。分配给element的值是一个java对象,并且可以通过变量被引用。例如:如 果$element 是一个java的Product类,并且这个产品的名字可以通过调用他的getName()方法得到。

    #foreach ( list.keySet()) Key: list.get($key) <br> #end

    提示:velocity中大小写敏感。

    Velocity还特别提供了得到循环次数的方法,$velocityCount变量的名字是Velocity默认的名字。

    11、velocityCount变量在配置文件中定义
      # Default name of the loop counter
      # variable reference.
      directive.foreach.counter.name = velocityCount
      # Default starting value of the loop
      # counter variable reference.
      directive.foreach.counter.initial.value = 1

    12、#include与#parse导入脚本

      #include( "one.gif","two.txt","three.htm" )

            #parse ("parsefoo.vm")

    #include和#parse的作用都是引入本地文件, 为了安全的原因,被引入的本地文件只能在TEMPLATE_ROOT目录下。

    区别:

    (1) 与#include不同的是,#parse只能指定单个对象。而#include可以有多个

    如果您需要引入多个文件,可以用逗号分隔就行: #include ("one.gif", "two.txt", "three.htm" ) 在括号内可以是文件名,但是更多的时候是使用变量的: #include ( “greetings.txt”, $seasonalstock )

    (2) #include被引入文件的内容将不会通过模板引擎解析;

    而#parse引入的文件内容Velocity将解析其中的velocity语法并移交给模板,意思就是说相当与把引入的文件copy到文件中。

    #parse是可以递归调用的,例如:如果dofoo.vm包含如下行:

    Count down.<br>

    #set ($count = 8)

    #parse ("parsefoo.vm")

    <br>All done with dofoo.vm!

    那么在parsefoo.vm模板中,你可以包含如下内容:

    $count

    #set($count = $count - 1)

    #if ( $count > 0 )<br>

    #parse( "parsefoo.vm" )

    #else

    <br>All done with parsefoo.vm!

    #end

    注意:在vm中使用#parse来嵌套另外一个vm时的变量共享问题。如:
    ->a.vm 里嵌套 b.vm;
    ->a.vm 里定义了变量 $param;
    ->b.vm 里可以直接使用$param,无任何限制。
    但需要特别注意的是,如果b.vm里同时定义有变量$param,则b.vm里将使用b.vm里定义的值

    13、#stop 停止执行并返回

    14、定义宏Velocimacros ,相当于函数 支持包含功能

    Velocity中的宏我们可以理解为函数。

    ①宏的定义

      #macro( 宏的名称 $参数1 $参数2 ... )
       语句体(函数体)

      #end

    ②宏的调用

      #宏的名称($参数1 $参数2 ...)

           注意:参数之间用空格隔开

    例:
      #macro( tablerows $color $somelist )
      #foreach( $something in $somelist )
       <tr><td bgcolor=$color>$something</td></tr>
      #end
      #end

    15、Range Operator
      #foreach( $foo in [1..5] )

    16、内置对象

        Velocity内置了一些对象,在vm模版里可以直接调用,列举如下:
        $request、$response、$session,另外,模板内还可以使用 $msg内的消息工具访问 Struts 的国际化资源,达到简便实现国际化的方法。

    17、数组访问

        对数组的访问在Velocity中存在问题,因为Velocity只能访问对象的方法,而数组又是一个特殊的Array,所以虽然数组可以进行循环列举,但却不能定位访问特定位置的元素,如 strs[2],数组对固定位置元素的访问调用了Array的反射方法get(Object array, int index),而Velocity没能提供这样的访问,所以数组要么改成List等其他类容器的方式来包装,要么就通过公用Util类的方式来提供,传入数组对象和要访问的位置参数,从而达到返回所需值的目的。


    展开全文
  • Velocity开发指南

    2020-06-01 18:17:49
    Velocity 历史悠久的免费java模板引擎。官网:http://velocity.apache.org/ Velocity是基于Java的模板引擎,这是一种简单而强大的开发工具,可让您轻松创建和呈现用于格式化和显示数据的文档 *.vm :Velocity ...

    简介

    Velocity 历史悠久的免费java模板引擎。官网:http://velocity.apache.org/

    Velocity是基于Java的模板引擎,这是一种简单而强大的开发工具,可让您轻松创建和呈现用于格式化和显示数据的文档

     

    *.vm :Velocity 模板文件

    VTL : Velocity Template Language

    使用Velocity模板引擎时的需要关注两部分:Velocity模板Java代码调用

     

    Velocity模板由VTL引擎上下文对象构成;

    Java代码调用部分则负责初始Velocity引擎构建引擎上下文对象加载Velocity模板启动模版渲染

    而Velocity模板与Java代码调用部分通信的纽带就是引擎上下文对象了。

     

    Velocity被移植到不同的平台上,如.Net的NVelocity和js的Velocity.js,虽然各平台在使用和实现上略有差别,但大部分语法和引擎核心的实现是一致的,因此学习成本降低不少哦。

     

    版本要求

    Velocity2.1以上版本要求jdk1.8以上

     

    Velocity2.2的maven 依赖

    <dependency>
      <groupId>org.apache.velocity</groupId>
      <artifactId>velocity-engine-core</artifactId>
      <version>2.2</version>
    </dependency>
    ​
    <dependency>
      <groupId>org.apache.velocity.tools</groupId>
      <artifactId>velocity-tools-generic</artifactId>
      <version>3.0</version>
    </dependency>
    ​
    <dependency>
      <groupId>org.apache.velocity.tools</groupId>
      <artifactId>velocity-tools-view</artifactId>
      <version>3.0</version>
    </dependency>
    ​
    <dependency>
      <groupId>org.apache.velocity.tools</groupId>
      <artifactId>velocity-tools-view-jsp</artifactId>
      <version>3.0</version>
    </dependency>

     

    其它所有版本官方下载地址:http://archive.apache.org/dist/velocity/engine/

     

    Velocity1.7要求jdk1.4版本以上。官网地址:http://velocity.apache.org/engine/1.7/

    1.7 api doc地址:https://tool.oschina.net/apidocs/apidoc?api=velocity-1.7

     

     

    快速入门

    Example2.java

    import java.io.StringWriter;
    import org.apache.velocity.app.Velocity;
    import org.apache.velocity.VelocityContext;
    ​
    public class Example2
    {
        public static void main( String args[] )
        {
            /* 首先,初始化运行时引擎,使用默认的配置 */
    ​
            Velocity.init();
    ​
            /* 创建Context对象,然后把数据放进去 */
    ​
            VelocityContext context = new VelocityContext();
    ​
            context.put("name", "Velocity");
            context.put("project", "Jakarta");
    ​
            /* 渲染模板 */
    ​
            StringWriter w = new StringWriter();
    ​
            Velocity.mergeTemplate("testtemplate.vm", context, w );
            System.out.println(" template : " + w );
    ​
            /* 渲染字符串 */
    ​
            String s = "We are using $project $name to render this.";
            w = new StringWriter();
            Velocity.evaluate( context, w, "mystring", s );
            System.out.println(" string : " + w );
        }
    }

     

    在运行程序之前,我们需要把模板文件testtemplate.vm放到与程序相同的目录下(因为我们使用默认配置,默认配置中指定的模板加载路径就是程序的当前目录)

    testtemplate.vm

    Hi! This $name from the $project project.

     

    总结

    首先,你还是需要先创建一个context,放进你需要的数据。

    然后合并内容

     

    Velocity的Java编码

    以下内容转自:https://www.cnblogs.com/fsjohnhuang/p/4112866.html 肥仔John

    模板与宿主环境通信

    模板指的是使用VTL编写的Velocity模板,宿主环境指的是Java代码调用部分。而两者通信的纽带就是引擎上下文对象( VelocityContext实例 ),下面是常用的 VelocityContext实例 方法。

     

    // 构造函数,入参为上下文的键值对集
    VelocityContext(Map context)
    // 添加上下文的键值对
    Object put(String key, Object value)
    // 从上下文获取指定键的值
    Object get(String key)
    // 检查上下文中是否存在指定的键值对
    boolean containsKey(Object key)
    // 获取所有键
    Object[] getKeys()
    // 移除指定键
    Object remove(Object key)
    // 获取上下文链中邻近的上下文对象
    Context getChainedContext()

     

    宿主环境向模板传值

    // 1. 通过构造函数传值
    HashMap<String, String> baseCtx = new HashMap<String, String>();
    baseCtx.put("version", "1");
    VelocityContext ctx = new VelocityContext(baseCtx);
    ​
    // 2. 通过put传值
    ctx.put("author", "fsjohnhuang");

     

    注意键值对中值的数据类型为

    Integer、Long等简单数据类型的装箱类型;

    String类型

    Object子类

    Object[] 数组类型,从1.6开始Velocity将数组类型视为 java.util.List 类型看待,因此模板中可调用 size() 、 get(intindex) 和 isEmpty() 的变量方法;

    java.util.Collection子类;

    java.util.Map子类;

    java.util.Iterator对象;

    java.util.Enumeration对象。

    除此之外,我们还可以将一个静态类赋予到上下文对象中,如 java.lang.Math静态类

    ctx.put("Math", java.lang.Math.class);

     

    模板向宿主环境传值

    1. 通信示例1——通过引擎上下文对象获取变量

    模板文件frm.vm

    #set($action="./submit")
    <form action="$action">
      .........
    </form>

    Java代码部分

    VelocityContext ctx = new VelocityContext();
    VelocityEngine ve = new VelocityEngine();
    StringWriter sw = new StringWriter();
    ve.mergeTemplate("frm.vm", ctx, sw);
    String actionStr = ctx.get("action");
    System.out.println(actionStr); // 显示./submit

     

    2. 通信示例2——通过副作用修改变量、属性值

    模板文件change.vm

    $people.put("john", "john huang")
    #set($version = $version + 1)

    Java代码部分

    VelocityContext ctx = new VelocityContext();
    ctx.put("version", 1);
    HashMap<String, String> people = new HashMap<String,String>();
    ctx.put("people", people);
    VelocityEngine ve = new VelocityEngine();
    StringWriter sw = new StringWriter();
    ve.mergeTemplate("change.vm", ctx, sw);
    System.out.println(ctx.get("version")); // 显示2
    System.out.println(people.get("john")); //显示john huang

     

    上述示例表明在模板中对引用类型实例进行操作时,操作结果将影响到该引用类型实例本身,因此必须谨慎操作。

    引擎上下文链

     

    也叫容器链,目前最常用的就是提供层次数据访问和工具箱

    VelocityContext context1 = new VelocityContext();
    ​
    context1.put("name","Velocity");
    context1.put("project", "Jakarta");
    context1.put("duplicate", "I am in context1");
    ​
    VelocityContext context2 = new VelocityContext( context1 );
    ​
    context2.put("lang", "Java" );
    context2.put("duplicate", "I am in context2");
    ​
    template.merge( context2, writer );

     

    所谓引擎上下文链就是将原有的上下文对象赋予给新建的上下文对象,从而达到上下文内的键值对复用。具体代码如下:

    VelocityContext ctx1 = new VelocityContext();
    ctx1.put("name", "fsjohuang");
    ctx1.put("version", 1);
    VelocityContext ctx2 = new VelocityContext(ctx1);
    ctx2.put("version", 2);
    ​
    System.out.println(ctx2.get("name")); // 显示fsjohnhuang
    System.out.println(ctx2.get("version")); // 显示2

    就是当前上下文对象没有该键值对时,则查询上下文链的对象有没有该键值对,有则返回,无则继续找链上的其他上下文对象,直到找到该键值对或遍历完所有链上的上下文对象。

    但VelocityContext实例除了put、get方法外,还有remove、getKeys、containsKey方法,它们的行为又是如何的呢?下面我们通过源码来了解吧!

     

    官网中涉及的java编码部分

    自定义属性

    /opt/templates

    ...
    ​
    import java.util.Properties;
     ...
    ​
    public static void main( String args[] )
    {
        /* 首先,我们还是初始化运行时引擎  */
    ​
        Properties p = new Properties();
        p.setProperty("file.resource.loader.path", "/opt/templates");
        Velocity.init( p );
    ​
     ...

     

    虽然Velocity允许你创建自己的容器类来满足特殊的需求和技术(比如像一个直接访问LDAP服务器的容器),一个叫VelocityContext的基本实现类已经作为发行版的一部分提供给你。

    VelocityContext适合所有的一般需求,所以我们强烈推荐你使用VelocityContext这个容器。只有在特殊情况和高级应用中,才需要你扩展或者创建你自己的容器实现。

     

    for和foreach()遍历对象的支持

    Velocity支持几种集合类型在VTL中使用foreach()语句:

    Object []

    普通对象数组 如果一个类中提供了迭代器接口,Velocity会自动包装你的数组

    Velocity现在允许模板设计者把数组当作定长链表来处理(Velocity 1.6中就是这样)

    java.util.Collection

    Velocity通过iterator()方法返回一个迭代器在循环中使用

    java.util.Map

    Velocity通过接口的values()方法返回一个Collection接口,iterator()方法在它上面调用来检索用于循环的迭代器。

    java.util.Iterator

    目前只是暂时支持,迭代器不能重置

    如果一个未初始化的迭代器被放进了容器,并且在多个foreach()语句中使用,如果第一个foreach()失败了,后面的都会被阻塞,因为迭代器不会重启

    java.util.Enumeration

    和java.util.Iterator一样

     

    对于Iterator和Enumeration,推荐只有在万不得已的情况下才把它们放进容器,你也应该尽可能地让Velocity找到合适的、可复用的迭代接口。

     

    Vector v = new Vector();
    v.addElement("Hello");
    v.addElement("There");
    ​
    context.put("words", v.iterator() );//不推荐
    context.put("words", v );
    
    对静态类的支持

    context.put("Math", Math.class);

    这样你就可以在模板中用$Math引用调用java.lang.Math中的任何公有静态方法。

    java.lang.Math这样的类不提供任何公有的构造函数,但是它包含了有用的静态方法

     

    Servlet使用Velocity

    web.xml 中配置Velocity

     

    http://velocity.apache.org/tools/devel/view-servlet.html

     

    <!-- Define Velocity template handler -->
    <servlet>
      <servlet-name>velocity</servlet-name>
      <servlet-class>
        org.apache.velocity.tools.view.VelocityViewServlet
      </servlet-class>
    ​
      <!-- 
        Unless you plan to put your tools.xml and velocity.properties
        under different folders or give them different names, then these
        two init-params are unnecessary.  The
        VelocityViewServlet will automatically look for these files in
        the following locations.
        -->
      <init-param>
        <param-name>org.apache.velocity.toolbox</param-name>
        <param-value>/WEB-INF/tools.xml</param-value>
      </init-param>
    ​
      <init-param>
        <param-name>org.apache.velocity.properties</param-name>
        <param-value>/WEB-INF/velocity.properties</param-value>
      </init-param>
    </servlet>
    ​
    <!-- Map *.vm files to Velocity -->
    <servlet-mapping>
      <servlet-name>velocity</servlet-name>
      <url-pattern>*.vm</url-pattern>
    </servlet-mapping>

     

    tools.xml就像定义了一个工具箱,里面放着很多工具,比如有个“扳手”。

    具体示例:考虑考虑让我们的朋友乔恩(Jon)从真实的工具箱中抓取我们的“扳手”。乔恩只需要知道我们想要哪个扳手。他不需要知道扳手做什么,也不需要知道我们打算如何做。

    Velocity Toolbox的工作方式与上面的例子相同,我们仅需指定所需的工具,然后Velocity引擎就可以在vm模板中使用任何在工具箱Tool.xml中定义好的公共方法来处理其余的工作。

     

    PipeWrench.java

    public class PipeWrench {
        public String getSize() {
            return "Large Pipe Wrench!";
        }
    }

    tools.xml

    <?xml version="1.0"?>
    <tools>
      <toolbox scope="application">
        <tool key="wrench" class="PipeWrench"/>
      </toolbox>
    </tools>

    .vm模板中可以使用:

    $wrench.size.

     

    VM模板

    官方VTL指南:

    http://velocity.apache.org/engine/2.2/vtl-reference.html

     

    VTL: Velocity Template Language

     

    以下内容转自:https://www.cnblogs.com/fsjohnhuang/p/4112866.html 肥仔John

    注释

    1. 行注释

    ## 行注释内容

    2. 块注释

    #*
    块注释内容1块注释内容2
    *#

    3. 文档注释

    #**
    文档注释内容1
    文档注释内容2
    *#

    踩过的坑 

    块注释和文档注释虽然均不输出到最终结果上,但会导致最终结果出现一行空行。使用行注释则不会出现此情况。

    直接输出的内容

    也就是不会被引擎解析的内容。

    #[[
    直接输出的内容1
    直接输出的内容2
    ]]#

    引用

    引用语句就是对引擎上下文对象中的属性进行操作

    语法方面分为常规语法( $属性 )和正规语法( ${属性} )

    在普通模式下上述两种写法,当引擎上下文对象中没有对应的属性时,最终结果会直接输出 $属性 或 ${属性} ,若要不输出则需要改写为 $!属性 和 $!{属性} 。

    1. 变量(就是引擎上下文对象的属性)

    $变量名, 常规写法,若上下文中没有对应的变量,则输入字符串"$变量名"
    ${变量名}, 常规写法,若上下文中没有对应的变量,则输入字符串"${变量名}" 
    $!变量名, 常规写法,若上下文中没有对应的变量,则输入空字符串"" 
    $!{变量名}, 常规写法,若上下文中没有对应的变量,则输入空字符串""

    变量的命名规则:

    由字母、下划线(_)、破折号(-)和数字组成,而且以字母开头。

    变量的数据类型为:

    Integer、Long等简单数据类型的装箱类型;

    String类型

    Object子类

    Object[] 数组类型,从1.6开始Velocity将数组类型视为 java.util.List 类型看待,因此模板中可调用 size() 、 get(int index) 和 isEmpty() 的变量方法;

    java.util.Collection子类;

    java.util.Map子类;

    java.util.Iterator对象;

    java.util.Enumeration对象。

     

    2. 属性(就是引擎上下文对象的属性的属性)

    $变量名.属性, 常规写法
    ${变量名.属性}, 正规写法
    $!变量名.属性, 常规写法
    $!{变量名.属性}, 正规写法

    属性搜索规则:

    Velocity采用一种十分灵活的方式搜索变量的属性, 具体如下:

    // 假如引用$var.prop,那么Velocity将对prop进行变形,然后在$var对象上尝试调用 // 变形和尝试的顺序如下

    1. $var.getprop()

    2. $var.getProp()

    3. $var.get("prop")

    4. $var.isProp()

    // 对于$var.Prop则如下

    1. $var.getProp()

    2. $var.getprop()

    3. $var.get("Prop")

    4. $var.isProp()

    因此获取 java.util.Map 对象的键值时可以简写为 $map.key ,Velocity会自动转为 $map.get("key") 来搜索!

    3. 方法(就是引擎上下文对象的属性的方法)

    $变量名.方法([入参1[, 入参2]*]?), 常规写法
    ${变量名.方法([入参1[, 入参2]*]?)}, 正规写法
    $!变量名.方法([入参1[, 入参2]*]?), 常规写法
    $!{变量名.方法([入参1[, 入参2]*]?)}, 正规写法

    引用方法实际就是方法调用操作,关注点返回值入参副作用的情况如下:

    1. 方法的返回值将输出到最终结果中

    1. 入参的数据类型

    $变量 或 $属性,数据类型参考第一小节;
    范围操作符(如:[1..2]或[$arg1..$arg2]),将作为java.util.ArrayList处理
    字典字面量(如:{a:"a",b:"b"}),将作为java.util.Map处理
    数字字面量(如:1),将自动装箱或拆箱匹配方法定义中的int或Integer入参
    1. 副作用

    // 若操作如java.util.Map.put方法,则会修改Java代码部分中的Map对象键值对
    $map.put("key", "new value")

     

    指令

    指令主要用于定义重用模块、引入外部资源、流程控制。指令以 # 作为起始字符。

    #set:向引擎上下文对象添加属性或对已有属性进行修改

    格式: #set($变量 = 值) ,具体示例如下:

    #set($var1 = $other)
    #set($var1.prop1 = $other)
    #set($var = 1)
    #set($var = true)
    #set($var = [1,2])
    #set($var = {a:"a", b:"b"})
    #set($var = [1..3])
    #set($var = [$arg1..$arg2])
    #set($var = $var1.method())
    #set($var = $arg1 + 1)
    #set($var = "hello")
    #set($var = "hello $var1") // 双引号可实现字符串拼接(coffeescript也是这样哦!),假设$var1为fsjohnhuang,则$var为hello fsjohnhuang
    #set($var = 'hello $var1') // 单引号将不解析其中引用,假设$var1为fsjohnhuang,则$var为hello $var1

    作用域明显是全局有效的。

    #if:条件判断

    格式:

    #if(判断条件)
      .........
    #elseif(判断条件)
      .........
    #else
      .........
    #end

    通过示例了解判断条件:

    #if($name)   //$name不为false、null和undefined则视为true
    $name
    #elseif($job == "net") // ==和!=两边的变量将调用其toString(),并对比两者的返回值
    Net工程师
    #elseif($age <= 16) // 支持<=,>=,>,<逻辑运算符
    未成年劳工
    #elseif(!$married) // 支持!逻辑运算符
    未婚
    #elseif($age >= 35 && !$married) // 支持&&,||关系运算符
    大龄未婚青年
    #end

    #foreach:循环

    格式:

    #foreach($item in $items)
        ..........
    #end

    $item 的作用范围为#foreach循环体内。

    $items 的数据类型为 Object[]数组 、 [1..2] 、 [1,2,3,4] 、 {a:"a",b:"b"} 和含 public Iterator iterator() 方法的对象,具体如下:

    java.util.Collection子类,Velocity会调用其iterator方法获取Iterator对象
    java.util.Map子类,Velocity会调用value()获取Collection对象,然后调用调用其iterator方法获取Iterator对象
    java.util.Iterator对象,直接将该Iterator对象添加到上下文对象中时,由于Iterator对象为只进不退的操作方式,因此无法被多个#foreach指令遍历
    java.util.Enumeration对象,直接将该Enumeration对象添加到上下文对象中时,由于Iterator对象为只进不退的操作方式,因此无法被多个#foreach指令遍历

    内置属性$foreach.count ,用于指示当前循环的次数,从0开始。可以通过配置项 directive.foreach.maxloops 来限制最大的循环次数,默认值为-1(不限制)。

     

    示例——使用Vector和Iterator的区别:

    模板:

    #macro(show)
    #foreach($letter in $letters)
    $letter
    #end
    #end
    #show()

    java代码:

    Vector<String> v = new Vector<String>();
    v.add("a");
    v.add("b");
    VelocityContext ctx = new VelocityContext();
    ctx.put("letters",v);
    Template t = Velocity.getTemplate("模板路径");
    StringWriter sw = new StringWriter();
    t.merge(ctx,sw);
    System.out.println(sw.toString());
    // 结果
    // a
    // b
    // a
    // b
    ​
    ctx.put("letters",v.iterator());
    // 结果
    // a
    //

    #break:跳出循环

    #foreach($item in $items)
    #if($item == "over")
    #break;
    #end
    $item
    #end

    #stop:中止模板解析操作

    #set($cmd="stop")
    $cmd
    #if($cmd == "stop")
    #stop
    #end
    $cmd  // 该语句将不执行

    #include引入外部资源

    (引入的资源不被引擎所解析)

    格式: #include(resource[ otherResource]*)

    resource、otherResource可以为单引号或双引号的字符串,也可以为$变量,内容为外部资源路径。注意为相对路径,则以引擎配置的文件加载器加载路径作为参考系,而不是当前模板文件的路径为参考系。

    #parse引入外部资源

    (引入的资源将被引擎所解析)

    格式: #parse(resource)

    resource可以为单引号或双引号的字符串,也可以为$变量,内容为外部资源路径。注意为相对路径,则以引擎配置的文件加载器加载路径作为参考系,而不是当前模板文件的路径为参考系。

    由于#parse指令可能会引起无限递归引入的问题,因此可通过配置项 directive.parse.max.depth来限制最大递归引入次数,默认值为10.

    #macro:定义重用模块(可带参数)

    定义格式:

    #macro(宏名 [$arg[ $arg]*]?)
       .....
    #end

    调用格式:

    #宏名([$arg[ $arg]]?)

    示例1——定义与调用位于同一模板文件时,无需遵守先定义后使用的规则

    #log("What a happy day")
    #macro(log $msg)
    log message: $msg
    #end

    示例2——定义与调用位于不同的模板文件时,需要遵守先定义后使用的规则

    ## 模板文件macro.vm#macro(log $msg)
    log message: $msg
    #end
    ## 模板文件main.vm
    #parse("macro.vm")
    #log("What a happy day")

    原理解析:Velocity引擎会根据模板生成语法树并缓冲起来然后再执行,因此宏定义和调用位于同一模板文件时,调用宏的时候它已经被引擎识别并初始化了(类似js中的hosit)。

    若定义与调用位于不同的模板文件中时,由于 #parse 是引擎解析模板文件时才被执行来引入外部资源并对其中的宏定义进行初始化,因此必须遵循先定义后使用的规则。

     

    我们可配置全局宏库,配置方式如下:

    Properties props = new Properties();
    // velocimacro.library的值为模板文件的路径,多个路径时用逗号分隔
    // velocimacro.library的默认值为VM_global_library.vm 
    props.setProperty("velocimacro.library", "global_macro1.vm,global_macro2.vm");
    VelocityEngine ve = new VelocityEngine(props);

    另外#macro还有另一种传参方式——$!bodyContent

    #macro(say)
    $!bodyContent
    #end
    #@say()Hello World#end
    // 结果为Hello World

    #define:定义重用模块(不带参数)

    #define($log)
    hello log!
    #end
    $log

    可视为弱版#macro,一般不用,了解就好了。

    #evaluate:动态计算

    示例:

    #set($name = "over")
    #evalute("#if($name=='over')over#{else}not over#end") // 输出over

    一般不用,了解就好了。

    转义符 

    通过 \ 对 $ 和 #进行转义,导致解析器不对其进行解析处理。

    #set($test='hello')
    $test ## 结果:hello
    \$test ## 结果:$test
    \\$test ## 结果:\hello
    \\\$test ## 结果:\$test
    ​
    $!test ## 结果:hello
    $\!test ## 结果:$!test
    $\\!test ## 结果:$\!test
    $\\\!test ## 结果:$\\!test

     

    模板实践

    内容引自:https://www.cnblogs.com/fsjohnhuang/p/4112328.html 肥仔

     

    示例结果是生成如下的html表单:

    <form action="./submit">
    <div>
      <label for="title">标题:</label>
      <input type="text" id="title" name="title"/>
    </div>
    <div>
      <label for="brief">摘要:</label>
      <input type="text" id="brief" name="brief"/>
    </div>
    <div>
      <label for="sex">性别:</label>
      <select id="sex" name="sex">
        <option value="0">男</option>
        <option value="1">女</option>
      </select>
    </div>
    <div>
      <label for="job">职业:</label>
      <select id="job" name="job">
        <option value="0">Java工程师</option>
        <option value="1">Net工程师</option>
      </select>
    </div>
    </form>

    引入依赖项——velocity-1.7-dep.jar

    模板文件frm.vm

    ##表单模板
    ##@author fsjohnhuang
    ##@version 1.0
    ## 引入外部模板文件
    #parse('macro.vm')
    ## 主逻辑
    <form action="$action">
    #foreach($input in $inputs)
    #input($input.title $input.id)
    #end
    #foreach($select in $selects)
    #select($select.title $select.id $select.items)
    #end
    </form>

    模板文件macro.vm

    ## 生成input表单元素区域的宏
    #macro(input $title $id)
    <div>
      <label for="$id">$title</label>
      <input type="text" id="$id" name="$id"/>
    </div>
    #end
    ## 生成select表单元素区域的宏
    #macro(select $title $id $items)
    <div>
      <label for="$id">$title</label>
      <select id="$id" name="$id">
    ## VTL指令紧贴左侧才能确保结果的排版正常(不会有多余空格)
    #foreach($key in $items.keySet())
        <option value="$key">$items.get($key)</option>
    #end
      </select>
    </div>
    #end

    Java代码

    public static void main(String[] args) {
            // 初始化模板引擎
            Properties props = new Properties();
            props.put("file.resource.loader.path", ".\\vm");
            VelocityEngine ve = new VelocityEngine(props);
            // 配置引擎上下文对象
            VelocityContext ctx = new VelocityContext();
            ctx.put("action", "./submit");
            ArrayList<HashMap<String, String>> inputs = new ArrayList<HashMap<String,String>>();
            HashMap<String, String> input1 = new HashMap<String, String>();
            input1.put("id", "title");
            input1.put("title", "标题:");
            inputs.add(input1);
            HashMap<String, String> input2 = new HashMap<String, String>();
            input2.put("id", "brief");
            input2.put("title", "摘要:");
            inputs.add(input2);
            ctx.put("inputs", inputs);
            ArrayList<HashMap<String, Object>> selects = new ArrayList<HashMap<String,Object>>();
            HashMap<String, Object> select1 = new HashMap<String, Object>();
            selects.add(select1);
            select1.put("id", "sex");
            select1.put("title", "性别:");
            HashMap<Integer, String> kv1 = new HashMap<Integer, String>();
            kv1.put(0, "男");
            kv1.put(1, "女");
            select1.put("items", kv1);
            HashMap<String, Object> select2 = new HashMap<String, Object>();
            selects.add(select2);
            select2.put("id", "job");
            select2.put("title", "职业:");
            HashMap<Integer, String> kv2 = new HashMap<Integer, String>();
            kv2.put(0, "Java工程师");
            kv2.put(1, "Net工程师");
            select2.put("items", kv2);
            ctx.put("selects", selects);
            // 加载模板文件
            Template t = ve.getTemplate("test.vm");
            StringWriter sw = new StringWriter();
            // 渲染模板
            t.merge(ctx, sw);
            System.out.print(sw.toString());
        }

     

    参考文章

     

    开发指南原文地址:

    http://velocity.apache.org/engine/devel/developer-guide.html#Introduction

    用户指南原文地址:

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

    中文翻译开发指南地址:

    https://ifeve.com/velocity-guide/

    肥仔 john优秀网文地址:

    https://www.cnblogs.com/fsjohnhuang/p/4114653.html

    展开全文
  • Velocity教程

    万次阅读 多人点赞 2016-08-20 17:29:50
    Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取在java语言中定义的对象,从而实现界面和java代码的真正分离,这意味着可以使用velocity替代jsp的开发模式了(实际上笔者所在的公司已经这么做了...

    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文件如下:

    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来加载vm文件。然后我们就可以往VelocityContext这个Velocity容器中存放对象了,在vm文件中我们可以取出这些变量,从而进行模板输出.

    2.2 编写hellovelocity.vm文件

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

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

    控制台输出如下:

    hello Velocity
    1
    2

    2.3 Velocity的基本语法

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

    3.1 变量

    在Velocity中也有变量的概念,使用$符声明变量,可以声明变量也可以对变量进行赋值(变量是弱类型的)。另外还可以使用$取出在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

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

    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 parse和include指令

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

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

    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方法,可以自定义转发规则

    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文件中可以获得在Context域或request等域中存放的值。默认情况下,会在资源根路径下搜索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文件,可以自定义vm文件加载方式,指定编码等。当然,也可以不配置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

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

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

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

    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文件是所有要展示的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. 附录及参考文献

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

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

    展开全文
  • Velocity入门

    万次阅读 多人点赞 2017-07-27 15:07:37
    Velocity是一个基于Java的模板引擎。它允许任何人使用简单而强大的模板语言来引用Java代码中定义的对象。当Velocity用于Web开发时,Web设计人员可以与Java程序员并行工作,以根据模型 - 视图 - 控制器(MVC)模型...
  • Velocity $ 和$! 区别

    2018-11-03 21:54:13
    输出指令 ${}过滤输出 输出表达式的计算结果,并进行过滤,比如:过滤变量中的HTML标签。 格式: ${expression} ...如果你需要更强的过滤,请自行实现Filter,并配置到value.filters。...如果输...
  • Velocity1

    2020-01-07 16:54:24
    Velocity是什么?一个java的后端模板引擎,后缀名是.vm 常用指令: "#"用来标识Velocity的脚本语句,包括#set、#if 、#else、#end、#foreach、#end、#iinclude、#parse、#macro等; 如: #if($info.imgs) <...
  • Velocity ${} 和$!{}、!${}区别

    千次阅读 2019-03-25 15:35:38
    在使用Velocity时经常会看到三种使用变量的情况 情况一:${name} 情况二:$!{name} 情况三:!${name} 那么三者之间到底有什么区别呢?莫慌!!!哈哈 情况一:${name} ${name}:输出表达式的计算结果,并进行...
  • Velocity Java 模板引擎 基本语法

    万次阅读 2018-10-15 13:15:44
    我们就先来执行第一步 Velocity 是什么。访问velocity官网进行快速了解。http://velocity.apache.org/ 大致内容如下: Velocity是一个基于Java的模板引擎。它允许任何人使用简单但功能强大的模板语言来引用Java...
  • SpringBoot1.5以上版本兼容被抛弃的velocity,详情说明见项目README.md。 # springboot1.5.x+ velocity2 springboot maven 搭建 springboot1.5以上因不支持velocity 问题的核心在于高版本的springboot已经删除了...
  • velocity模板 If / ElseIf / Else语法

    万次阅读 2017-03-18 23:40:01
    Velocity中的#if 指令允许在页面生成时,在IF条件为真的情况下包含文本。例如: #if( $foo ) Velocity! #end 变量 $foo 先求值,以决定是否为真。在这两种情况下为真: (i) $foo 是一个逻辑变量并具有真的值,...
  • 浅谈jsp、freemarker、velocity区别

    万次阅读 多人点赞 2020-04-15 18:48:17
    以前做web开发页面层用的基本就是就是,最近公司java项目页面层用的技术是velocity。听说jsp要淘汰,也不知道是真是假,但本人还是比较喜欢jsp的,下面是网上查找的javaweb项目页面3种技术的区别。 在java领域,表现...
  • 用springMVC+velocity时,当使用自定义标签,发现自定义标签无法注入spring的其它服务类,归根源码发现,velocity的源码中有一段,有一段代码永远获取的是新实例。所以,把这个地方的源码改了,所以使用这个的时候,...
  • Velocity.js 是velocity模板语法的javascript实现。Velocity 是基于Java的模板引擎,广泛应用在阿里集 体各个子公司。Velocity模板适用于大量模板使用的场景,支持复杂的逻辑运算,包含 基本数据类型、变量赋值和...
  • Velocity工作原理解析和优化

    千次阅读 2017-02-08 11:15:14
    在MVC开发模式下,View离不开模板引擎,在Java语言中模板引擎使用得最多是JSP、Velocity和FreeMarker,在MVC编程开发模式中,必不可少的一个部分是V的部分。V负责前端的页面展示,也就是负责生产最终的HTML,V部分...
  • 关于Java中如何使用velocity

    千次阅读 2018-11-30 15:09:23
    最近做项目,遇到后台Date时间类型传到前台显示为英文问题,本来是自己在结果前先将Date类型时间处理成String类型传至前台,后来觉得麻烦,发现可以使用Velocity直接前台调用java类方法进行类型转换。  我们先了解...
  • 真正有气质的淑女,从不炫耀她所拥有的一切,她不告诉别人她读过什么书,去过什么地方,有多少件...(3)velocity; (4)thymeleaf;2、jsp优点: 1、功能强大,可以写java代码 2、支持jsp标签(jsp tag) 3、支持表
  • Velocity详解及demo

    千次阅读 2018-03-02 16:55:36
    最近遇到了Velocity,需要使用到,就上网查询资料,自己写了个demo; 一、Velocity是什么? Velocity是一个基于Java的模板引擎,其提供了一个Context容器,在java代码里面我们可以往容器中存值,然后在vm文件中...
  • springboot+velocityLayout和velocity-tools

    千次阅读 2016-01-31 18:02:57
    velocity作为模板语言已经存在很久,近期接触下来感觉用的还行,  一: 先介绍下velocity-tools的好用之处,接下来再介绍如何整合。 整合了velocity-tools就不需要再导入什么标签了,这个velocity-tool中的...
  • 最近在写几个基于websocket的监控页面,改来改去(无产品参与,无PRD)到现在,产品希望用原来的模板(基于velocity),而我本身倾向于thymeleaf,(Velocity此前压根没用过啊而且1.5版本之后的spring boot是不支持...
1 2 3 4 5 ... 20
收藏数 77,428
精华内容 30,971
关键字:

velocity