zoukankan      html  css  js  c++  java
  • velocity学习总结

    什么是velocity

    velocity是一个基于Java的模板引擎,它可以实现彻底的前后端,前端不允许像jsp那样出现Java代码,而是利用context容器传递变量,在java代码里面我们可以往容器中存值,然后在vm文件中使用特定的语法获取(不知道和ajax+restful实现的前后端分离有没有差别,有时间看下底层代码)。velocity除了作为mvc的展现层以外,还可以实现一些特殊的功能,比如源代码生成,自动email和转换xml等,详情见使用 Velocity 模板引擎快速生成代码,velocity最新版本是17年发布的2.0版本

    如何使用velocity

    引入jar包

    • velocity-engine-core-x.x.x.jar: Velocity的核心jar包,它必须被引用.
    • velocity-engine-commons-logging-x.x.x.jar: 它用来绑定通用的日志信息Logging, 所有的日志信息将指向它. 用在连接Logging (包括”lib” 目录).
    • velocity-engine-slf4j-x.x.x.jar:它主要用来绑定SLF4J,所有的日志信息将指向它. 用在连接SLF4J (包括”lib” 目录).
    • velocity-engine-log4j-x.x.x.jar: 它主要是绑定Log4j日志,所有的日志消息将使用它. 用在连接Log4j (包括 “lib” 的目录).
    • velocity-engine-servlet-x.x.x.jar: 它主要用来绑定服务器日志. 使用在服务器容器中.

    maven工程

    在pom文件中引入依赖

    <dependency>
      <groupId>org.apache.velocity</groupId>
      <artifactId>velocity-engine-core</artifactId>
      <version>x.x.x</version>
    </dependency>
    

    如果想将velocity与Logging,SLF4J,log4j以及服务器logger日志集成,可以再pom文件中继续加入下面这些依赖

    <dependency>
      <groupId>org.apache.velocity</groupId>
      <artifactId>velocity-engine-commons-logging</artifactId>
      <version>x.x.x</version>
    </dependency>
     
    <dependency>
      <groupId>org.apache.velocity</groupId>
      <artifactId>velocity-engine-slf4j</artifactId>
      <version>x.x.x</version>
    </dependency>
     
    <dependency>
      <groupId>org.apache.velocity</groupId>
      <artifactId>velocity-engine-log4j</artifactId>
      <version>x.x.x</version>
    </dependency>
     
    <dependency>
      <groupId>org.apache.velocity</groupId>
      <artifactId>velocity-engine-servlet</artifactId>
      <version>x.x.x</version>
    </dependency>
    

    非maven工程

    非maven工程我们需要把jar包直接放入到工程的classpath中(lib文件夹下)

    基本用法

    引入jar包后,我们就可以使用velocity实现我们的前后端分离了。

    初始化velocity引擎

    前面我们说过,velocity允许我们在后台把数据放入到context容器里面,从而实现从在前端直接取出。编写VelocityTest.java如下

    package pers.marscheng.spring.test;
     
    import org.apache.velocity.Template;
    import org.apache.velocity.VelocityContext;
    import org.apache.velocity.app.VelocityEngine;
    import org.apache.velocity.runtime.RuntimeConstants;
    import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
     
    import java.io.StringWriter;
    import java.util.ArrayList;
    import java.util.List;
     
    /**
     * velocity测试类
     *
     * @author: marscheng
     * @date: 2018-04-02 下午3:47
     */
    public class VelocityTest {
        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("test.vm");
            // 将变量放入context容器
            VelocityContext ctx = new VelocityContext();
            ctx.put("name", "MarsCheng");
            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());
     
        }
    }
    

    编写vm文件

    test.vm文件如下:

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

    注意要把文件放在classpath目录下。如何确定classpath路径?可以调用以下命令打印出来

    System.out.println(ClassLoader.getSystemResource(""));
    


    执行VelocityTest.main,控制台会打印出:

    集成web工程

    velocity与spring集成时候还要加上velocity-tools的jar包,否则在加载bean的时候会报错

    <dependency>
       <groupId>org.apache.velocity</groupId>
       <artifactId>velocity-tools</artifactId>
       <version>2.0</version>
    </dependency>
    

    配置视图解析器,这么配置系统只能解析vm文件,可以配置多视图解析器(待研究,初步尝试了用order,但是貌似没有生效)

    <!-- 视图模式配置,velocity配置文件-->
    <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
       <property name="resourceLoaderPath" value="/WEB-INF/views" />
       <property name="configLocation" value="classpath:properties/velocity.properties" />
    </bean>
     
    <!-- 配置后缀 -->
    <bean id="velocityViewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
       <property name="suffix" value=".vm" />
    </bean>
    

    配置properties文件

    #encoding
    input.encoding=UTF-8
    output.encoding=UTF-8
     
    #autoreload when vm changed
    file.resource.loader.cache=false
    file.resource.loader.modificationCheckInterval=2
    velocimacro.library.autoreload=false
    

    在/WEB-INF/views路劲下写vm文件showUser.vm

    <!DOCTYPE html>
    <html>
    <head>
       <meta charset="UTF-8" pageEncoding="UTF-8">
       <title>User Index</title>
    </head>
    <body>
    <h3>hello ${user.name}</h3>
     
    </body>
    </html>
    

    其对应的controller层代码如下UserControllerImpl.java,这里的User是我们定义的一个用户javabean

    package pers.marscheng.spring.controller.impl;
     
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import pers.marscheng.spring.controller.UserController;
    import pers.marscheng.spring.dto.User;
     
    import javax.servlet.http.HttpServletRequest;
     
    /**
     * @author: marscheng
     * @date: 2018-04-03 下午3:05
     */
    @Controller
    @RequestMapping("/user")
    public class UserControllerImpl implements UserController {
     
        @Override
        @RequestMapping("/showUser")
        public String showUser(HttpServletRequest request, Model model) {
            User user = new User();
            user.setName("Mars");
            //存vm需要的参数
            model.addAttribute("user",user);
     
            return "showUser";
        }
    }
    

    然后我们访问http://localhost:8080/user/showUser,就可以看到对应的页面了

    velocity语法

    Velocity使用模板语言——VTL,用于前端的开发,接下来就来总结下常见的一些VTL语法。具体可以参考官方的翻译文档

    变量

    velocity中的变量用$作为前缀,它可以获取你在后台用Java定义的变量值,也可以在前端定义,然后使用。在vtl语法中用set表达式来定义(注意在表达式前面会有个#,这是velocity命令的写法,后面你会看到更多的如#if等)

    ##velocity的变量是弱类型,可以写成$a或者${a},右边可以是(变量引用,字面字符串,属性引用,方法引用,字面数字,数组列表)
    #set( $a = "Velocity" )
    

    循环

    velocity的循环结构如下所示,$list是个集合,$item表示遍历的每一项,$velocityCount是velocity的默认的变量,用来统计循环的次数

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

    条件控制

    条件控制的结构如下所示

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

    语句嵌套

    循环语句内可以嵌套循环语句,也可以嵌套条件语句#if

    #foreach ($element in $list)
        #foreach ($element in $list)
            This is $element. $velocityCount <br>inner<br>
        #end
        ## inner foreach 内循环结束
     ## outer foreach
    This is $element.
    $velocityCount <br>outer<br>
    #end
    

    注释

    velocity的注释用##表示

    关系和逻辑操作符

    velocity 也有表示与或非的操作符,和Java一样,都是&& || !,用法也同Java,如下面非的用法

    ##logical NOT
     
    #if( !$foo )
      <strong>NOT that</strong>
    #end
    

    velocity的宏相当于Java的函数

    宏定义

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

    宏调用

    ##参数用空格隔开
    #宏的名称($参数1 $参数2 …)
    

    #stop

    这个命令可以停止执行模板引擎并返回,可以用来debug

    #include与#parse

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

    区别在于:

    1.#include可以引入多个文件,#parse只能引入一个,如

    #include ("one.gif", "two.txt", "three.htm" )
    ##也可以使用变量名
    #include ( “greetings.txt”, $seasonalstock )
    

    2.#include引入的内容不会被模板引擎解析,而#parse引入的内容会被解析

    内置对象

    velocity和jsp一样,内置了一些对象,可以在vm模板中调用,如:$request、$response、$session等

  • 相关阅读:
    爱的感悟
    连点成图:享受创建图形的乐趣
    python实现动态更新远程机器列表的SSH登录脚本
    python生成数据库中所有表的DESC描述
    生活之美
    克服“测试怠惰”的习惯
    使用git和github托管个人项目
    连点成线
    一次合并数据库的经历
    python使用装饰器捕获异常
  • 原文地址:https://www.cnblogs.com/MarsCheng/p/8711053.html
Copyright © 2011-2022 走看看