velocity模板加载

时间:2023-03-09 22:05:32
velocity模板加载

http://hi.baidu.com/ly_dayu/item/828b09c5c3c5e547a8ba9409 
velocity使用基本来说比较简单,但在加载模板时老出问题,很多初学者经常会遇到找不到模板这种异常。本文就针对目前常用的三种模板加载方式做以说明。 
velocity模板加载

一、velocity默认的加载方式(文件加载方式)

  1. package com.velocity.test;
  2. import java.io.StringWriter;
  3. import java.util.Properties;
  4. import org.apache.velocity.VelocityContext;
  5. import org.apache.velocity.app.VelocityEngine;
  6. /**
  7. * 从文件中加载模板文件,即velocity默认的模板文件加载方式
  8. * @author welcome
  9. *
  10. */
  11. public class LoaderFromFile {
  12. public static void main(String[] args) throws Exception{
  13. //初始化参数
  14. Properties properties=new Properties();
  15. //设置velocity资源加载方式为file
  16. properties.setProperty("resource.loader", "file");
  17. //设置velocity资源加载方式为file时的处理类
  18. properties.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
  19. //实例化一个VelocityEngine对象
  20. VelocityEngine velocityEngine=new VelocityEngine(properties);
  21. //实例化一个VelocityContext
  22. VelocityContext context=new VelocityContext();
  23. //向VelocityContext中放入键值
  24. context.put("username", "张三");
  25. context.put("password", "123456789");
  26. context.put("age", "20");
  27. context.put("address", "陕西西安");
  28. context.put("blog", "http://blogjava.net/sxyx2008");
  29. //实例化一个StringWriter
  30. StringWriter writer=new StringWriter();
  31. //从vm目录下加载hello.vm模板,在eclipse工程中该vm目录与src目录平级
  32. velocityEngine.mergeTemplate("vm/hello.vm", "gbk", context, writer);
  33. System.out.println(writer.toString());
  34. }
  35. }

二、从类路径加载模板文件

  1. package com.velocity.test;
  2. import java.io.StringWriter;
  3. import java.util.Properties;
  4. import org.apache.velocity.VelocityContext;
  5. import org.apache.velocity.app.VelocityEngine;
  6. /**
  7. * 从class(类路径)中加载模板文件
  8. * @author welcome
  9. *
  10. */
  11. public class LoaderFromClass {
  12. public static void main(String[] args) throws Exception{
  13. //初始化参数
  14. Properties properties=new Properties();
  15. //设置velocity资源加载方式为class
  16. properties.setProperty("resource.loader", "class");
  17. //设置velocity资源加载方式为file时的处理类
  18. properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
  19. //实例化一个VelocityEngine对象
  20. VelocityEngine velocityEngine=new VelocityEngine(properties);
  21. //实例化一个VelocityContext
  22. VelocityContext context=new VelocityContext();
  23. //向VelocityContext中放入键值
  24. context.put("username", "张三");
  25. context.put("password", "123456789");
  26. context.put("age", "20");
  27. context.put("address", "陕西西安");
  28. context.put("blog", "http://blogjava.net/sxyx2008");
  29. //实例化一个StringWriter
  30. StringWriter writer=new StringWriter();
  31. //从src目录下加载hello.vm模板
  32. //假若在com.velocity.test包下有一个hello.vm文件,那么加载路径为com/velocity/test/hello.vm
  33. velocityEngine.mergeTemplate("com/velocity/test/hello.vm", "gbk", context, writer);
  34. //velocityEngine.mergeTemplate("hello.vm", "gbk", context, writer);
  35. System.out.println(writer.toString());
  36. }
  37. }

三、从jar文件中加载模板文件

  1. package com.velocity.test;
  2. import java.io.StringWriter;
  3. import java.util.Properties;
  4. import org.apache.velocity.VelocityContext;
  5. import org.apache.velocity.app.VelocityEngine;
  6. /**
  7. * 从jar文件中加载模板文件
  8. * @author welcome
  9. *
  10. */
  11. public class LoaderFromJar {
  12. public static void main(String[] args) throws Exception{
  13. //初始化参数
  14. Properties properties=new Properties();
  15. //设置velocity资源加载方式为jar
  16. properties.setProperty("resource.loader", "jar");
  17. //设置velocity资源加载方式为file时的处理类
  18. properties.setProperty("jar.resource.loader.class", "org.apache.velocity.runtime.resource.loader.JarResourceLoader");
  19. //设置jar包所在的位置
  20. properties.setProperty("jar.resource.loader.path", "jar:file:WebRoot/WEB-INF/lib/vm.jar");
  21. //实例化一个VelocityEngine对象
  22. VelocityEngine velocityEngine=new VelocityEngine(properties);
  23. //实例化一个VelocityContext
  24. VelocityContext context=new VelocityContext();
  25. //向VelocityContext中放入键值
  26. context.put("username", "张三");
  27. context.put("password", "123456789");
  28. context.put("age", "20");
  29. context.put("address", "陕西西安");
  30. context.put("blog", "http://blogjava.net/sxyx2008");
  31. //实例化一个StringWriter
  32. StringWriter writer=new StringWriter();
  33. //从/WebRoot/WEB-INF/lib/vm.jar中加载hello.vm模板  vm.jar的目录结构为vm/hello.vm
  34. velocityEngine.mergeTemplate("vm/hello.vm", "gbk", context, writer);
  35. System.out.println(writer.toString());
  36. }
  37. }

velocity模板路径又一解http://www.blogjava.net/patterns/archive/2006/11/28/velocity_template_path_another_method.html 
研究hibernatesynchronizer的源码,看到他将velocity模板和编译的类一起打包在jar包中,在获得模板时使用

  1. Xobject.class.getClassLoader().getResourceAsStream("/templates/xx.vm")

获得流,然后再将转变成字符串

  1. public static String getStringFromStream(InputStream is) throws IOException {
  2. if (null == is)
  3. return null;
  4. try {
  5. InputStreamReader reader = new InputStreamReader(is);
  6. char[] buffer = new char[1024];
  7. StringWriter writer = new StringWriter();
  8. int bytes_read;
  9. while ((bytes_read = reader.read(buffer)) != -1) {
  10. writer.write(buffer, 0, bytes_read);
  11. }
  12. return (writer.toString());
  13. } finally {
  14. if (null != is)
  15. is.close();
  16. }
  17. }

最后调用velocity的方法

  1. 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的同志来说,这个例子可以是你参照学习的良好实例

  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements.  See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership.  The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License.  You may obtain a copy of the License at
  9. *
  10. *   http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied.  See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. import java.io.BufferedWriter;
  20. import java.io.OutputStreamWriter;
  21. import java.io.StringWriter;
  22. import java.util.ArrayList;
  23. import java.util.Properties;
  24. import org.apache.velocity.Template;
  25. import org.apache.velocity.VelocityContext;
  26. import org.apache.velocity.app.Velocity;
  27. import org.apache.velocity.app.VelocityEngine;
  28. import org.apache.velocity.exception.MethodInvocationException;
  29. import org.apache.velocity.exception.ParseErrorException;
  30. /**
  31. * This class is a simple demonstration of how the Velocity Template Engine
  32. * can be used in a standalone application using the Velocity utility class.
  33. *
  34. * It demonstrates two of the 'helper' methods found in the org.apache.velocity.util.Velocity
  35. * class, mergeTemplate() and evaluate().
  36. *
  37. *
  38. * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  39. * @version $Id: Example2.java 463298 2006-10-12 16:10:32Z henning $
  40. */
  41. public class Example2
  42. {
  43. public static ArrayList getNames()
  44. {
  45. ArrayList list = new ArrayList();
  46. list.add("ArrayList element 1");
  47. list.add("ArrayList element 2");
  48. list.add("ArrayList element 3");
  49. list.add("ArrayList element 4");
  50. return list;
  51. }
  52. public static void main( String args[] )
  53. {
  54. /* first, we init the runtime engine.  Defaults are fine. */
  55. Properties p = new Properties();
  56. //设置输入输出编码类型。和这次说的解决的问题无关
  57. p.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
  58. p.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
  59. //这里加载类路径里的模板而不是文件系统路径里的模板
  60. p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
  61. //也可以用下面方法指定一个绝对路径,不过这样要求你所有的模板都放在该路径下,是有局限的
  62. //p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "模板路径");
  63. try
  64. {
  65. Velocity.init(p);
  66. }
  67. catch(Exception e)
  68. {
  69. System.out.println("Problem initializing Velocity : " + e );
  70. return;
  71. }
  72. /* lets make a Context and put data into it */
  73. VelocityContext context = new VelocityContext();
  74. context.put("name", "Velocity");
  75. context.put("project", "阿帕奇");
  76. context.put("list", getNames());
  77. /* lets render a template */
  78. StringWriter w = new StringWriter();
  79. try
  80. {
  81. Velocity.mergeTemplate("example2.vm", "UTF-8", context, w );
  82. }
  83. catch (Exception e )
  84. {
  85. System.out.println("Problem merging template : " + e );
  86. }
  87. System.out.println(" template : " + w );
  88. /*
  89. *  lets dynamically 'create' our template
  90. *  and use the evaluate() method to render it
  91. */
  92. //这个例子也同时告诉我们可以先从文件系统读取一个文件到字符串,然后进行我们想要的操作
  93. String s = "We are using $project $name to render this.";
  94. w = new StringWriter();
  95. try
  96. {
  97. Velocity.evaluate( context, w, "mystring", s );
  98. }
  99. catch( ParseErrorException pee )
  100. {
  101. /*
  102. * thrown if something is wrong with the
  103. * syntax of our template string
  104. */
  105. System.out.println("ParseErrorException : " + pee );
  106. }
  107. catch( MethodInvocationException mee )
  108. {
  109. /*
  110. *  thrown if a method of a reference
  111. *  called by the template
  112. *  throws an exception. That won't happen here
  113. *  as we aren't calling any methods in this
  114. *  example, but we have to catch them anyway
  115. */
  116. System.out.println("MethodInvocationException : " + mee );
  117. }
  118. catch( Exception e )
  119. {
  120. System.out.println("Exception : " + e );
  121. }
  122. System.out.println(" string : " + w );
  123. ///////////////////////////////////////////////////////
  124. //其他方法: 1分别指定路径,此方法可以设定不同的路径 (也可是相对的。在eclipse下是工程目录)
  125. try {
  126. VelocityEngine velocityEngine = new VelocityEngine();
  127. Properties properties = new Properties();
  128. //也可以在这里指定绝对路径。当指定相对路径时, 在不同的环境下是有区别的。
  129. //比如把程序部署到tomcat以后,相对路径相对到哪里是个很恶心的事情。
  130. String basePath = "vm";
  131. //可设置绝对路径
  132. //String basePath = "F:/";
  133. properties.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, basePath);
  134. velocityEngine.init(properties);
  135. Template template = velocityEngine.getTemplate("example2.vm");
  136. BufferedWriter writer = new BufferedWriter(
  137. new OutputStreamWriter(System.out));
  138. template.merge(context, writer);
  139. writer.flush();
  140. writer.close();
  141. } catch (Exception e) {
  142. e.printStackTrace();
  143. }
  144. }
  145. }