velocity模板加載
http://hi.baidu.com/ly_dayu/item/828b09c5c3c5e547a8ba9409
velocity使用基本來說比較簡單,但在加載模板時老出問題,很多初學者經常會遇到找不到模板這種異常。本文就針對目前常用的三種模板加載方式做以說明。
一、velocity默認的加載方式(文件加載方式)
- package com.velocity.test;
- import java.io.StringWriter;
- import java.util.Properties;
- import org.apache.velocity.VelocityContext;
- import org.apache.velocity.app.VelocityEngine;
- /**
- * 從文件中加載模板文件,即velocity默認的模板文件加載方式
- * @author welcome
- *
- */
- public class LoaderFromFile {
- public static void main(String[] args) throws Exception{
- //初始化參數
- Properties properties=new Properties();
- //設置velocity資源加載方式為file
- properties.setProperty("resource.loader", "file");
- //設置velocity資源加載方式為file時的處理類
- properties.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
- //實例化一個VelocityEngine對象
- VelocityEngine velocityEngine=new VelocityEngine(properties);
- //實例化一個VelocityContext
- VelocityContext context=new VelocityContext();
- //向VelocityContext中放入鍵值
- context.put("username", "張三");
- context.put("password", "123456789");
- context.put("age", "20");
- context.put("address", "陜西西安");
- context.put("blog", "http://blogjava.net/sxyx2008");
- //實例化一個StringWriter
- StringWriter writer=new StringWriter();
- //從vm目錄下加載hello.vm模板,在eclipse工程中該vm目錄與src目錄平級
- velocityEngine.mergeTemplate("vm/hello.vm", "gbk", context, writer);
- System.out.println(writer.toString());
- }
- }
二、從類路徑加載模板文件
- package com.velocity.test;
- import java.io.StringWriter;
- import java.util.Properties;
- import org.apache.velocity.VelocityContext;
- import org.apache.velocity.app.VelocityEngine;
- /**
- * 從class(類路徑)中加載模板文件
- * @author welcome
- *
- */
- public class LoaderFromClass {
- public static void main(String[] args) throws Exception{
- //初始化參數
- Properties properties=new Properties();
- //設置velocity資源加載方式為class
- properties.setProperty("resource.loader", "class");
- //設置velocity資源加載方式為file時的處理類
- properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
- //實例化一個VelocityEngine對象
- VelocityEngine velocityEngine=new VelocityEngine(properties);
- //實例化一個VelocityContext
- VelocityContext context=new VelocityContext();
- //向VelocityContext中放入鍵值
- context.put("username", "張三");
- context.put("password", "123456789");
- context.put("age", "20");
- context.put("address", "陜西西安");
- context.put("blog", "http://blogjava.net/sxyx2008");
- //實例化一個StringWriter
- StringWriter writer=new StringWriter();
- //從src目錄下加載hello.vm模板
- //假若在com.velocity.test包下有一個hello.vm文件,那麽加載路徑為com/velocity/test/hello.vm
- velocityEngine.mergeTemplate("com/velocity/test/hello.vm", "gbk", context, writer);
- //velocityEngine.mergeTemplate("hello.vm", "gbk", context, writer);
- System.out.println(writer.toString());
- }
- }
三、從jar文件中加載模板文件
- package com.velocity.test;
- import java.io.StringWriter;
- import java.util.Properties;
- import org.apache.velocity.VelocityContext;
- import org.apache.velocity.app.VelocityEngine;
- /**
- * 從jar文件中加載模板文件
- * @author welcome
- *
- */
- public class LoaderFromJar {
- public static void main(String[] args) throws Exception{
- //初始化參數
- Properties properties=new Properties();
- //設置velocity資源加載方式為jar
- properties.setProperty("resource.loader", "jar");
- //設置velocity資源加載方式為file時的處理類
- properties.setProperty("jar.resource.loader.class", "org.apache.velocity.runtime.resource.loader.JarResourceLoader");
- //設置jar包所在的位置
- properties.setProperty("jar.resource.loader.path", "jar:file:WebRoot/WEB-INF/lib/vm.jar");
- //實例化一個VelocityEngine對象
- VelocityEngine velocityEngine=new VelocityEngine(properties);
- //實例化一個VelocityContext
- VelocityContext context=new VelocityContext();
- //向VelocityContext中放入鍵值
- context.put("username", "張三");
- context.put("password", "123456789");
- context.put("age", "20");
- context.put("address", "陜西西安");
- context.put("blog", "http://blogjava.net/sxyx2008");
- //實例化一個StringWriter
- StringWriter writer=new StringWriter();
- //從/WebRoot/WEB-INF/lib/vm.jar中加載hello.vm模板 vm.jar的目錄結構為vm/hello.vm
- velocityEngine.mergeTemplate("vm/hello.vm", "gbk", context, writer);
- System.out.println(writer.toString());
- }
- }
velocity模板路徑又一解http://www.blogjava.net/patterns/archive/2006/11/28/velocity_template_path_another_method.html
研究hibernatesynchronizer的源碼,看到他將velocity模板和編譯的類一起打包在jar包中,在獲得模板時使用
- Xobject.class.getClassLoader().getResourceAsStream("/templates/xx.vm")
獲得流,然後再將轉變成字符串
- public static String getStringFromStream(InputStream is) throws IOException {
- if (null == is)
- return null;
- try {
- InputStreamReader reader = new InputStreamReader(is);
- char[] buffer = new char[1024];
- StringWriter writer = new StringWriter();
- int bytes_read;
- while ((bytes_read = reader.read(buffer)) != -1) {
- writer.write(buffer, 0, bytes_read);
- }
- return (writer.toString());
- } finally {
- if (null != is)
- is.close();
- }
- }
最後調用velocity的方法
- Velocity.evaluate(Context context, java.io.Writer out, java.lang.String logTag, java.lang.String instring)
從而生成文件。居然不知道velocity有這樣的方法,挺無知的,為了路徑焦頭爛額,終於得解了。總結一下技巧:
1、Xobject.class.getClassLoader().getResourceAsStream("/templates/xx.vm")相對路徑獲得流;
2、Velocity.evaluate(...)方法使用;
velocity模板路徑: http://zhyt710.iteye.com/blog/235250
遇到的velocity加載模板時的路徑問題。
於是查閱資料解決。最後綜合velocity自己帶的例子的example1和example2,改寫了一個例子。怎樣解決的在例子的註釋中已經說的很明確。對於初學velocity的同誌來說,這個例子可以是你參照學習的良好實例
- /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- import java.io.BufferedWriter;
- import java.io.OutputStreamWriter;
- import java.io.StringWriter;
- import java.util.ArrayList;
- 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.MethodInvocationException;
- import org.apache.velocity.exception.ParseErrorException;
- /**
- * This class is a simple demonstration of how the Velocity Template Engine
- * can be used in a standalone application using the Velocity utility class.
- *
- * It demonstrates two of the ‘helper‘ methods found in the org.apache.velocity.util.Velocity
- * class, mergeTemplate() and evaluate().
- *
- *
- * @author <a href="mailto:[email protected]">Geir Magnusson Jr.</a>
- * @version $Id: Example2.java 463298 2006-10-12 16:10:32Z henning $
- */
- public class Example2
- {
- public static ArrayList getNames()
- {
- ArrayList list = new ArrayList();
- list.add("ArrayList element 1");
- list.add("ArrayList element 2");
- list.add("ArrayList element 3");
- list.add("ArrayList element 4");
- return list;
- }
- public static void main( String args[] )
- {
- /* first, we init the runtime engine. Defaults are fine. */
- Properties p = new Properties();
- //設置輸入輸出編碼類型。和這次說的解決的問題無關
- p.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
- p.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
- //這裏加載類路徑裏的模板而不是文件系統路徑裏的模板
- p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
- //也可以用下面方法指定一個絕對路徑,不過這樣要求你所有的模板都放在該路徑下,是有局限的
- //p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "模板路徑");
- try
- {
- Velocity.init(p);
- }
- catch(Exception e)
- {
- System.out.println("Problem initializing Velocity : " + e );
- return;
- }
- /* lets make a Context and put data into it */
- VelocityContext context = new VelocityContext();
- context.put("name", "Velocity");
- context.put("project", "阿帕奇");
- context.put("list", getNames());
- /* lets render a template */
- StringWriter w = new StringWriter();
- try
- {
- Velocity.mergeTemplate("example2.vm", "UTF-8", context, w );
- }
- catch (Exception e )
- {
- System.out.println("Problem merging template : " + e );
- }
- System.out.println(" template : " + w );
- /*
- * lets dynamically ‘create‘ our template
- * and use the evaluate() method to render it
- */
- //這個例子也同時告訴我們可以先從文件系統讀取一個文件到字符串,然後進行我們想要的操作
- String s = "We are using $project $name to render this.";
- w = new StringWriter();
- try
- {
- Velocity.evaluate( context, w, "mystring", s );
- }
- catch( ParseErrorException pee )
- {
- /*
- * thrown if something is wrong with the
- * syntax of our template string
- */
- System.out.println("ParseErrorException : " + pee );
- }
- catch( MethodInvocationException mee )
- {
- /*
- * thrown if a method of a reference
- * called by the template
- * throws an exception. That won‘t happen here
- * as we aren‘t calling any methods in this
- * example, but we have to catch them anyway
- */
- System.out.println("MethodInvocationException : " + mee );
- }
- catch( Exception e )
- {
- System.out.println("Exception : " + e );
- }
- System.out.println(" string : " + w );
- ///////////////////////////////////////////////////////
- //其他方法: 1分別指定路徑,此方法可以設定不同的路徑 (也可是相對的。在eclipse下是工程目錄)
- try {
- VelocityEngine velocityEngine = new VelocityEngine();
- Properties properties = new Properties();
- //也可以在這裏指定絕對路徑。當指定相對路徑時, 在不同的環境下是有區別的。
- //比如把程序部署到tomcat以後,相對路徑相對到哪裏是個很惡心的事情。
- String basePath = "vm";
- //可設置絕對路徑
- //String basePath = "F:/";
- properties.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, basePath);
- velocityEngine.init(properties);
- Template template = velocityEngine.getTemplate("example2.vm");
- BufferedWriter writer = new BufferedWriter(
- new OutputStreamWriter(System.out));
- template.merge(context, writer);
- writer.flush();
- writer.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
velocity模板加載