Velocity的研究,在JAVA工程中使用

先写一个pojo提供测试Book.java

package org.test;

import java.util.Date;

public class Book {
	
	private String bookid;//id
	private String bookname;//书名
	private Date publishDate;//出版日期
	private int bookprice;//价格
	
	public String getBookid() {
		return bookid;
	}
	public String getBookname() {
		return bookname;
	}
	public Date getPublishDate() {
		return publishDate;
	}
	public int getBookprice() {
		return bookprice;
	}
	public void setBookid(String bookid) {
		this.bookid = bookid;
	}
	public void setBookname(String bookname) {
		this.bookname = bookname;
	}
	public void setPublishDate(Date publishDate) {
		this.publishDate = publishDate;
	}
	public void setBookprice(int bookprice) {
		this.bookprice = bookprice;
	}
	

}


测试类VelocityTestUtil.java

package org.test;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.RuntimeSingleton;

public class VelocityTestUtil {
	
	public void velocityTestOne(String templateFile) {
		try {
			System.out.println("revoke method : velocityTestOne");
			//单例实例化  RuntimeSingleton.init();
			//Velocity velocity = new Velocity();
			//velocity.init();
			//Velocity.init();//同上
			//非单例实例化 ri = new RuntimeInstance();,如果同时使用多个Velocity,必须使用这个方法!
			VelocityEngine velocityEngine = new VelocityEngine();
			velocityEngine.init();
			
			VelocityContext context = new VelocityContext();
			//context.put( "name", new String("Velocity") );
			context.put("mylist", getBooks());
			Template template = null;//模版
			try {
				//template = velocity.getTemplate(templateFile,"UTF-8");
				//template = Velocity.getTemplate(templateFile,"UTF-8");//单例。注意设置编码,避免中文乱码
				template = velocityEngine.getTemplate(templateFile,"UTF-8");//非单例。注意设置编码,避免中文乱码
			} catch (ResourceNotFoundException e1) {
				System.out.println("VelocityTestUtil error,ResourceNotFoundException:"
						+ templateFile);
			} catch (ParseErrorException e2) {
				System.out.println("VelocityTestUtil error,ParseErrorException:"
						+ templateFile + ":" + e2);
			}
			BufferedWriter writer = writer = new BufferedWriter(
					new OutputStreamWriter(System.out));//这里我直接打印了,也可以写到其他文件,或用于页面展示

			if (template != null){
				template.merge(context, writer);
			}
			writer.flush();
			writer.close();
		} catch (Exception e) {
			System.out.println(e);
		}
	}

	public void velocityTestWithPropertiesSet(String templateFile,Properties prop) {
		try {
			System.out.println("revoke method : velocityTestWithPropertiesSet");
			//单例实例化  RuntimeSingleton.init();
			//Velocity velocity = new Velocity();
			//velocity.init();
			//Velocity.init();//同上
			//非单例实例化 ri = new RuntimeInstance();,如果同时使用多个Velocity,必须使用这个方法!
			VelocityEngine velocityEngine = new VelocityEngine();
			velocityEngine.init(prop);
			System.out.println("ss--"+velocityEngine.getProperty(Velocity.FILE_RESOURCE_LOADER_PATH));
			
			VelocityContext context = new VelocityContext();
			context.put("mylist", getBooks());
			Template template = null;//模版
			try {
				//template = velocity.getTemplate(templateFile,"UTF-8");
				//template = Velocity.getTemplate(templateFile,"UTF-8");//单例。注意设置编码,避免中文乱码
				template = velocityEngine.getTemplate(templateFile,"UTF-8");//非单例。注意设置编码,避免中文乱码
			} catch (ResourceNotFoundException e1) {
				System.out.println("VelocityTestUtil error,ResourceNotFoundException:"
						+ templateFile);
			} catch (ParseErrorException e2) {
				System.out.println("VelocityTestUtil error,ParseErrorException:"
						+ templateFile + ":" + e2);
			}
			BufferedWriter writer = writer = new BufferedWriter(
					new OutputStreamWriter(System.out));//这里我直接打印了,也可以写到其他文件,或用于页面展示

			if (template != null){
				template.merge(context, writer);
			}
			writer.flush();
			writer.close();
		} catch (Exception e) {
			System.out.println(e);
		}
	}
	
	public ArrayList getBooks() {
		ArrayList list = new ArrayList();
		
		Book bk1=new Book();
		bk1.setBookid("id1");
		bk1.setBookname("基督山伯爵");
		bk1.setBookprice(23);
		bk1.setPublishDate(new Date());
		
		Book bk2=new Book();
		bk2.setBookid("id2");
		bk2.setBookname("三个火枪手");
		bk2.setBookprice(35);
		bk2.setPublishDate(new Date());

		list.add(bk1);
		list.add(bk2);

		return list;
	}

	public static void main(String[] args) {
		// bin/org/test/book.vm  (java project)
		// WebContent/WEB-INF/classes/org/test/book.vm  (web project)
		
		//VelocityTestUtil v1 = new VelocityTestUtil();
		//v1.velocityTestOne("bin/org/test/book.vm");//路径默认工程路径
		
		VelocityTestUtil v2 = new VelocityTestUtil();
		
	    Properties prop = new Properties(); 
	    //设置输入输出编码类型
	    prop.setProperty(Velocity.INPUT_ENCODING, "UTF-8"); 
	    prop.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8"); 
	    //指定一个绝对路径作为模版路径
	    //  D:/MyProject/my-workSpace/Mytest/bin/org/test
	    prop.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "D:/MyProject/my-workSpace/Mytest/bin/org/test");
	    
//	    v2.velocityTestOne("bin/org/test/book2.vm"); //当FILE_RESOURCE_LOADER_PATH=.或/
	    v2.velocityTestWithPropertiesSet("book2.vm",prop);
	    
	}
}


模版文件:book.vm

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
我的第一个模版,哈哈
<table border="1px">
<th>书名</th>
<th>价格</th>
<th>出版日期</th>
#foreach( $book in $list )
<tr>
  <td>$book.bookname</td>
  <td>$book.bookprice </td>
  <td>$book.publishDate </td>
</tr>
#end
<table>
</body>
</html>


模版文件:book2.vm

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<table border="1px">
<th>书名</th>
<th>价格</th>
<th>出版日期</th>
#foreach( $book in $mylist )
<tr>
  <td>$book.getBookname()</td>
  <td>$book.getBookprice() </td>
  <td>${book.getPublishDate()} </td>
</tr>
#end
<table>

<br>其他调用方式:注意context.put("mylist", getBooks());中放入变量的名称是mylist,
如果换成list就取不到值,但是在book.vm中用的是list就可以取到值,可能Velocity认为第一个容器名称作为
唯一的名称吧,在这里我第一次使用的是mylist,所以就认为是mylist,好像和context.put("mylist", getBooks())没有关系;
取不到值的velocity表达式将显示表达式本身,除非,你在$符号后加!,
这样在取不到值的情况下,将显示空字符串""<br>
$mylist[0]<br>
$mylist[0].getBookname()<br><input type="text" name="price" value="$!mylist[0].getBookname()"/><br>
${mylist[1].getBookname()}<br><input type="text" name="price" value="$!{mylist[1].getBookname()}"/><br>

$list[0]<br>
$list[0].getBookname()<br><input type="text" name="price" value="$!list[0].getBookname()"/><br>
${list[1].getBookname()}<br><input type="text" name="price" value="$!{list[1].getBookname()}"/><br>

## siggle line comment
#* multiple line comment
multiple line comment
multiple line comment *#

#set($hello = "你好,Velocity!")
欢迎语:$hello

#set($goodbook = "三个火枪手")
#set($toohighprice = 50)
#set( $allpricelist = [10, 20, $toohighprice] ) ## ArrayList
#set( $allpricelmap = {"lowprice" : 10, "middleprice" : 20,"highprice":$toohighprice } ) ## Map
#foreach( $book in $mylist )
	#if($book.getBookname() == $goodbook)
<font color="red">$book.getBookname()是本好书!</font>,定价:$allpricelist.get(0)
	#end
	##list test
	#if($book.getBookprice()<= $allpricelist.get(0))
<font color="blue">$book.getBookname(),跳楼低价!</font>
    #elseif($book.getBookprice()<= $allpricelist[1])
<font color="blue">$book.getBookname(),超低价!</font>
    #elseif($book.getBookprice()<= $allpricelist[2])
<font color="blue">$book.getBookname(),价格合理!</font>
    #else
<font color="blue">$book.getBookname(),太贵了!</font>
	#end
#end

##map test
#foreach( $key in $allpricelmap.keySet() )
    <font color="green">Key: $key -> Value: $allpricelmap.get($key)</font>
#end
最高价限额:$allpricelmap.get("highprice")元。

#set($source = "abc")
#set($select = "123")
#set($dynamicsource = "$source$select")
#evaluate($dynamicsource)  ##类似js中eval方法
或者$dynamicsource

#define($defobj)  
  你好哇,$who
#end
#set( $who = '世界!' )
变量中的变量计算结果:$defobj

##宏定义,类似JAVA中定义一个方法
#macro( tablerows $color $somelist )
	#foreach( $something in $somelist )
	    <tr><td bgcolor="$color">$something</td></tr>
	#end
#end
##宏调用
#set( $greatlakes = ["海贼","火影","死神","圣斗","最游"] )
#set( $color = "blue" )
<table>
    #tablerows( $color $greatlakes )
</table>

##反斜杠使用
#set($xie = "反斜杠文字")
$xie,'$xie',"$xie";;;\$xie,\\$xie,\\\$xie

\#if( $xie=="反斜杠文字" )
    语法中'#'的转义
\#end
#if( $xie=="反斜杠文字" )
    语法中'#'的转义
#end

</body>
</html>

引入其他模版,如果改变根路径,记得这里也要改变,如下:
##parse("bin/org/test/book.vm") ##file.resource.loader.path=.或/
#parse("book.vm")  ##file.resource.loader.path=D:/MyProject/my-workSpace/Mytest/bin/org/test




运行VelocityTestUtil

控制台打印:

revoke method : velocityTestWithPropertiesSet
ss--D:/MyProject/my-workSpace/Mytest/bin/org/test
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<table border="1px">
<th>书名</th>
<th>价格</th>
<th>出版日期</th>
<tr>
  <td>基督山伯爵</td>
  <td>23 </td>
  <td>Thu Oct 18 09:40:07 CST 2012 </td>
</tr>
<tr>
  <td>三个火枪手</td>
  <td>35 </td>
  <td>Thu Oct 18 09:40:07 CST 2012 </td>
</tr>
<table>

<br>其他调用方式:注意context.put("mylist", getBooks());中放入变量的名称是mylist,
如果换成list就取不到值,但是在book.vm中用的是list就可以取到值,可能Velocity认为第一个容器名称作为
唯一的名称吧,在这里我第一次使用的是mylist,所以就认为是mylist,好像和context.put("mylist", getBooks())没有关系;
取不到值的velocity表达式将显示表达式本身,除非,你在$符号后加!,
这样在取不到值的情况下,将显示空字符串""<br>
org.test.Book@1a5ab41<br>
基督山伯爵<br><input type="text" name="price" value="基督山伯爵"/><br>
三个火枪手<br><input type="text" name="price" value="三个火枪手"/><br>

$list[0]<br>
$list[0].getBookname()<br><input type="text" name="price" value=""/><br>
${list[1].getBookname()}<br><input type="text" name="price" value=""/><br>



欢迎语:你好,Velocity!

  			<font color="blue">基督山伯爵,价格合理!</font>
    	<font color="red">三个火枪手是本好书!</font>,定价:10
			<font color="blue">三个火枪手,价格合理!</font>
    
    <font color="green">Key: lowprice -> Value: 10</font>
    <font color="green">Key: middleprice -> Value: 20</font>
    <font color="green">Key: highprice -> Value: 50</font>
最高价限额:50元。

abc123  或者abc123

变量中的变量计算结果:  你好哇,世界!


<table>
    		    <tr><td bgcolor="blue">海贼</td></tr>
		    <tr><td bgcolor="blue">火影</td></tr>
		    <tr><td bgcolor="blue">死神</td></tr>
		    <tr><td bgcolor="blue">圣斗</td></tr>
		    <tr><td bgcolor="blue">最游</td></tr>
	</table>

反斜杠文字,'反斜杠文字',"反斜杠文字";;;$xie,\反斜杠文字,\$xie

#if( 反斜杠文字=="反斜杠文字" )
    语法中'#'的转义
#end
    语法中'#'的转义

</body>
</html>

引入其他模版,如果改变根路径,记得这里也要改变,如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
我的第一个模版,哈哈
<table border="1px">
<th>书名</th>
<th>价格</th>
<th>出版日期</th>
<table>
</body>
</html>  




对比输出结果,Velocity的配置,调用,模版语法都很清楚明了了。

附上工程结构图:

关于velocity的配置本身有默认配置,

velocity-1.7.jar中
org/apache/velocity/runtime/defaults/velocity.properties
这个文件时velocity的属性默认配置文件

runtime.log.logsystem.class = org.apache.velocity.runtime.log.AvalonLogChute,org.apache.velocity.runtime.log.Log4JLogChute,org.apache.velocity.runtime.log.CommonsLogLogChute,org.apache.velocity.runtime.log.ServletLogChute,org.apache.velocity.runtime.log.JdkLogChute

runtime.log = velocity.log
runtime.log.invalid.references = true

input.encoding=ISO-8859-1
output.encoding=ISO-8859-1


directive.foreach.counter.name = velocityCount
directive.foreach.counter.initial.value = 1
directive.foreach.maxloops = -1
directive.foreach.iterator.name = velocityHasNext
directive.set.null.allowed = false
directive.if.tostring.nullcheck = true
directive.include.output.errormsg.start = <!-- include error :
directive.include.output.errormsg.end   =  see error log -->
directive.parse.max.depth = 10

foreach.provide.scope.control = true

resource.loader = file

file.resource.loader.description = Velocity File Resource Loader
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path = .
file.resource.loader.cache = false
file.resource.loader.modificationCheckInterval = 2

string.resource.loader.description = Velocity String Resource Loader
string.resource.loader.class = org.apache.velocity.runtime.resource.loader.StringResourceLoader

velocimacro.permissions.allow.inline = true
velocimacro.permissions.allow.inline.to.replace.global = false
velocimacro.permissions.allow.inline.local.scope = false
velocimacro.context.localscope = false
velocimacro.max.depth = 20
velocimacro.arguments.strict = false
velocimacro.body.reference=bodyContent

runtime.references.strict = false
runtime.interpolate.string.literals = true

resource.manager.class = org.apache.velocity.runtime.resource.ResourceManagerImpl
resource.manager.cache.class = org.apache.velocity.runtime.resource.ResourceCacheImpl

parser.pool.class = org.apache.velocity.runtime.ParserPoolImpl
parser.pool.size = 20

runtime.introspector.uberspect = org.apache.velocity.util.introspection.UberspectImpl

introspector.restrict.packages = java.lang.reflect
introspector.restrict.classes = java.lang.Class
introspector.restrict.classes = java.lang.ClassLoader
introspector.restrict.classes = java.lang.Compiler
introspector.restrict.classes = java.lang.InheritableThreadLocal
introspector.restrict.classes = java.lang.Package
introspector.restrict.classes = java.lang.Process
introspector.restrict.classes = java.lang.Runtime
introspector.restrict.classes = java.lang.RuntimePermission
introspector.restrict.classes = java.lang.SecurityManager
introspector.restrict.classes = java.lang.System
introspector.restrict.classes = java.lang.Thread
introspector.restrict.classes = java.lang.ThreadGroup
introspector.restrict.classes = java.lang.ThreadLocal



所有可以设置的属性由org.apache.velocity.runtime.RuntimeConstants定义:

/*jadclipse*/// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) radix(10) lradix(10) 
// Source File Name:   RuntimeConstants.java

package org.apache.velocity.runtime;


public interface RuntimeConstants
{

    public static final String RUNTIME_LOG = "runtime.log";
    public static final String RUNTIME_LOG_LOGSYSTEM = "runtime.log.logsystem";
    public static final String RUNTIME_LOG_LOGSYSTEM_CLASS = "runtime.log.logsystem.class";
    public static final String RUNTIME_REFERENCES_STRICT = "runtime.references.strict";
    public static final String RUNTIME_REFERENCES_STRICT_ESCAPE = "runtime.references.strict.escape";
    /**
     * @deprecated Field RUNTIME_LOG_ERROR_STACKTRACE is deprecated
     */
    public static final String RUNTIME_LOG_ERROR_STACKTRACE = "runtime.log.error.stacktrace";
    /**
     * @deprecated Field RUNTIME_LOG_WARN_STACKTRACE is deprecated
     */
    public static final String RUNTIME_LOG_WARN_STACKTRACE = "runtime.log.warn.stacktrace";
    /**
     * @deprecated Field RUNTIME_LOG_INFO_STACKTRACE is deprecated
     */
    public static final String RUNTIME_LOG_INFO_STACKTRACE = "runtime.log.info.stacktrace";
    public static final String RUNTIME_LOG_REFERENCE_LOG_INVALID = "runtime.log.invalid.references";
    /**
     * @deprecated Field TRACE_PREFIX is deprecated
     */
    public static final String TRACE_PREFIX = " [trace] ";
    /**
     * @deprecated Field DEBUG_PREFIX is deprecated
     */
    public static final String DEBUG_PREFIX = " [debug] ";
    /**
     * @deprecated Field INFO_PREFIX is deprecated
     */
    public static final String INFO_PREFIX = "  [info] ";
    /**
     * @deprecated Field WARN_PREFIX is deprecated
     */
    public static final String WARN_PREFIX = "  [warn] ";
    /**
     * @deprecated Field ERROR_PREFIX is deprecated
     */
    public static final String ERROR_PREFIX = " [error] ";
    /**
     * @deprecated Field UNKNOWN_PREFIX is deprecated
     */
    public static final String UNKNOWN_PREFIX = " [unknown] ";
    public static final String COUNTER_NAME = "directive.foreach.counter.name";
    public static final String HAS_NEXT_NAME = "directive.foreach.iterator.name";
    public static final String COUNTER_INITIAL_VALUE = "directive.foreach.counter.initial.value";
    public static final String MAX_NUMBER_LOOPS = "directive.foreach.maxloops";
    public static final String SKIP_INVALID_ITERATOR = "directive.foreach.skip.invalid";
    public static final String SET_NULL_ALLOWED = "directive.set.null.allowed";
    public static final String DIRECTIVE_IF_TOSTRING_NULLCHECK = "directive.if.tostring.nullcheck";
    public static final String ERRORMSG_START = "directive.include.output.errormsg.start";
    public static final String ERRORMSG_END = "directive.include.output.errormsg.end";
    public static final String PARSE_DIRECTIVE_MAXDEPTH = "directive.parse.max.depth";
    public static final String DEFINE_DIRECTIVE_MAXDEPTH = "directive.define.max.depth";
    public static final String EVALUATE_CONTEXT_CLASS = "directive.evaluate.context.class";
    public static final String PROVIDE_SCOPE_CONTROL = "provide.scope.control";
    public static final String RESOURCE_MANAGER_CLASS = "resource.manager.class";
    public static final String RESOURCE_MANAGER_CACHE_CLASS = "resource.manager.cache.class";
    public static final String RESOURCE_MANAGER_DEFAULTCACHE_SIZE = "resource.manager.defaultcache.size";
    public static final String RESOURCE_MANAGER_LOGWHENFOUND = "resource.manager.logwhenfound";
    public static final String RESOURCE_LOADER = "resource.loader";
    public static final String FILE_RESOURCE_LOADER_PATH = "file.resource.loader.path";
    public static final String FILE_RESOURCE_LOADER_CACHE = "file.resource.loader.cache";
    public static final String EVENTHANDLER_REFERENCEINSERTION = "eventhandler.referenceinsertion.class";
    public static final String EVENTHANDLER_NULLSET = "eventhandler.nullset.class";
    public static final String EVENTHANDLER_METHODEXCEPTION = "eventhandler.methodexception.class";
    public static final String EVENTHANDLER_INCLUDE = "eventhandler.include.class";
    public static final String EVENTHANDLER_INVALIDREFERENCES = "eventhandler.invalidreferences.class";
    public static final String VM_LIBRARY = "velocimacro.library";
    public static final String VM_LIBRARY_DEFAULT = "VM_global_library.vm";
    public static final String VM_LIBRARY_AUTORELOAD = "velocimacro.library.autoreload";
    public static final String VM_PERM_ALLOW_INLINE = "velocimacro.permissions.allow.inline";
    public static final String VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL = "velocimacro.permissions.allow.inline.to.replace.global";
    public static final String VM_PERM_INLINE_LOCAL = "velocimacro.permissions.allow.inline.local.scope";
    public static final String VM_MESSAGES_ON = "velocimacro.messages.on";
    public static final String VM_CONTEXT_LOCALSCOPE = "velocimacro.context.localscope";
    public static final String VM_ARGUMENTS_STRICT = "velocimacro.arguments.strict";
    public static final String VM_MAX_DEPTH = "velocimacro.max.depth";
    public static final String VM_BODY_REFERENCE = "velocimacro.body.reference";
    public static final String INTERPOLATE_STRINGLITERALS = "runtime.interpolate.string.literals";
    public static final String INPUT_ENCODING = "input.encoding";
    public static final String OUTPUT_ENCODING = "output.encoding";
    public static final String ENCODING_DEFAULT = "ISO-8859-1";
    public static final String UBERSPECT_CLASSNAME = "runtime.introspector.uberspect";
    public static final String INTROSPECTOR_RESTRICT_PACKAGES = "introspector.restrict.packages";
    public static final String INTROSPECTOR_RESTRICT_CLASSES = "introspector.restrict.classes";
    public static final String STRICT_MATH = "runtime.strict.math";
    public static final String PARSER_POOL_CLASS = "parser.pool.class";
    public static final String PARSER_POOL_SIZE = "parser.pool.size";
    public static final String DEFAULT_RUNTIME_PROPERTIES = "org/apache/velocity/runtime/defaults/velocity.properties";
    public static final String DEFAULT_RUNTIME_DIRECTIVES = "org/apache/velocity/runtime/defaults/directive.properties";
    public static final int NUMBER_OF_PARSERS = 20;
}


/*
	DECOMPILATION REPORT

	Decompiled from: D:\MyProject\my-workSpace\Mytest\lib\velocity-1.7.jar
	Total time: 312 ms
	Jad reported messages/errors:
	Exit status: 0
	Caught exceptions:
*/


具体需要哪些配置,研究文档吧。

本例子只是研究Velocity的功能,所以在java工程做的例子。

以后有机会再web工程中使用再做研究吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值