专注人工智能在金融领域的应用

Velocity模板实例详解

Velocity单例模式是系统默认的模式, 这样在jvm(应用程序)或web aplication(一个web程序)中只存在一个Velocity engine实例共享使用。. 这对于配置和共享资源来说非常方便. 比如, 这非常适合用于支持 Servlet 2.2+ 的web application中,每一个web app持有它自己的唯一Velocity实例, 它们可以共享templates, a logger等资源. Singleton可以直接通过使用org.apache.velocity.app.Velocity 类, 如下例子:

单例模式:
  1.     
  2. import java.io.StringWriter;   
  3. import org.apache.velocity.app.Velocity;   
  4. import org.apache.velocity.VelocityContext;   
  5.     
  6. /**
  7.  *  
  8.  * @author wangbaocai.cn  
  9.  *  
  10.  */  
  11. public class Example2   
  12. {   
  13.     public static void main( String args[] )   
  14.     {   
  15.         /* first, we init the runtime engine. Defaults are fine. */  
  16.     
  17.         Velocity. init();   
  18.     
  19.         /* lets make a Context and put data into it */  
  20.     
  21.         VelocityContext context = new VelocityContext();   
  22.     
  23.         context.put( “name” , “wangbaocai.cn” );   
  24.         context.put( “website” , “wangbaocai.cn” );   
  25.     
  26.         /* lets render a template */  
  27.     
  28.         StringWriter w = new StringWriter();   
  29.     
  30.         Velocity. mergeTemplate( “testtemplate.vm” , context, w );   
  31.         System. out .println(“ template : ” + w );   
  32.     
  33.         /* lets make our own string to render */  
  34.     
  35.         String s = “We are using $website $name to render this.” ;   
  36.         w = new StringWriter();   
  37.         Velocity. evaluate( context, w, “mystring”, s );   
  38.         System. out .println(“ string : ” + w );   
  39.     }   
  40. }   
 testtemplate.vm文件默认路径为程序运行的目录。
多例模式:
  1.   
  2. import java.io.File;   
  3. import java.io.FileOutputStream;   
  4. import java.io.PrintWriter;   
  5. import java.io.Writer;   
  6.     
  7. import org.apache.velocity.Template;   
  8. import org.apache.velocity.VelocityContext;   
  9. import org.apache.velocity.app.Velocity;   
  10. import org.apache.velocity.app.VelocityEngine;   
  11.     
  12. /**
  13. * Velocity模板实例  
  14. *  
  15. * @author wangbaocai.cn  
  16. */  
  17. public class VelocityTest2 {   
  18.      /**
  19.      * 主函数  
  20.      *  
  21.      * @param args  
  22.      */  
  23.      public static void main(String[] args) {   
  24.           // 获取模板引擎   
  25.           VelocityEngine ve = new VelocityEngine();   
  26.           // 模板文件所在的路径   
  27.           String path = “D:/velocity/” ;   
  28.           // 设置参数   
  29.           ve.setProperty(Velocity. FILE_RESOURCE_LOADER_PATH , path);   
  30.           // 处理中文问题   
  31.           ve.setProperty(Velocity. INPUT_ENCODING , “GBK” );   
  32.           ve.setProperty(Velocity. OUTPUT_ENCODING , “GBK” );   
  33.           try {   
  34.                // 初始化模板   
  35.                ve.init();   
  36.                // 获取模板(hello.html)Velocity模板的名称   
  37.                Template template = ve.getTemplate( “hello.html” );   
  38.                // 获取上下文   
  39.                VelocityContext root = new VelocityContext();   
  40.                // 把数据填入上下文 (注意:与上面的对应)   
  41.                root.put( “name” , “wangbaocai.cn” );   
  42.                // 输出路径   
  43.                String outpath = “e:/helloworld.html” ;   
  44.                // 输出   
  45.                Writer mywriter = new PrintWriter( new FileOutputStream(new File(   
  46.                          outpath)));   
  47.                template.merge(root, mywriter);   
  48.                mywriter.flush();   
  49.           } catch (Exception e) {   
  50.                e.printStackTrace();   
  51.           }   
  52.      }   
  53. }   
hello.html模板内容如下:
  1. <!DOCTYPE HTML PUBLIC \”-//W3C//DTD HTML 4.0 Transitional//EN\”>  
  2. <HTML>  
  3. <HEAD>  
  4. <TITLE> New Document </TITLE>  
  5. </HEAD>  
  6. <BODY>  
  7. hello,$name!   
  8. </BODY>  
  9. </HTML>  
自定义ResourceLoader加载模板内容
以上例子是从模板文件中加载模板,然而有时候我们希望从数据库中加载模板,这时候我们可以使用String字符模板,如下:
方法一:
  1. import java.io.IOException;   
  2. import java.io.StringWriter;   
  3.     
  4. import org.apache.velocity.Template;   
  5. import org.apache.velocity.VelocityContext;   
  6. import org.apache.velocity.app.VelocityEngine;   
  7. import org.apache.velocity.runtime.resource.loader.StringResourceLoader;   
  8. import org.apache.velocity.runtime.resource.util.StringResourceRepository;   
  9.     
  10. /**   
  11. * @author wangbaocai.cn   
  12. *   
  13. */   
  14. public class velocitytest {   
  15.     
  16.      /**   
  17.      * @param args   
  18.      * @throws IOException   
  19.      */   
  20.      public static void main(String[] args) throws IOException {   
  21.            
  22.           VelocityEngine ve = new VelocityEngine();   
  23.     
  24.           ve.setProperty(VelocityEngine. RESOURCE_LOADER , ”string” );   
  25.     
  26.           ve.setProperty( ”string.resource.loader.class” ,   
  27.                     ”org.apache.velocity.runtime.resource.loader.StringResourceLoader” );   
  28.     
  29.           ve.init();   
  30.            
  31.           //创建资源库   
  32.     
  33.           StringResourceRepository repo = StringResourceLoader.getRepository();   
  34.     
  35.           String myTemplateName = “hello123″ ;   
  36.     
  37.           String myTemplate = “Hi, ${username}… this is some template! ${flag}#if($flag)<img src=\”$urlA\” border=0>#else<img src=\”noPhoto.jpg\”>#end”;   
  38.            
  39.           //模板资源存放 资源库 中   
  40.     
  41.           repo.putStringResource(myTemplateName, myTemplate);   
  42.            
  43.           Template template = ve.getTemplate(myTemplateName);   
  44.            
  45.            
  46.           //设置模板变量值   
  47.     
  48.           VelocityContext context = new VelocityContext();   
  49.     
  50.           context.put( ”username” , ”wangbaocai” );   
  51.     
  52.           context.put( ”flag” , false );   
  53.     
  54.           context.put( ”urlA” , ”wangbaocai.cn” );   
  55.            
  56.           //创建输出流   
  57.     
  58.           StringWriter writer = new StringWriter();   
  59.     
  60.           //把变量填充到模板中,并写入输出流文件中   
  61.     
  62.           template.merge(context, writer);   
  63.     
  64.           //关闭输出流   
  65.     
  66.           writer.close();   
  67.     
  68.           //显示输出流内容   
  69.     
  70.           System. out .println(writer);   
  71.      }   
  72. }  
方法二:
我们也可以自定义ResourceLoader来加载模板,如下:
  1.   
  2. import java.io.ByteArrayInputStream;   
  3. import java.io.InputStream;   
  4. import org.apache.commons.collections.ExtendedProperties;   
  5. import org.apache.velocity.exception.ResourceNotFoundException;   
  6. import org.apache.velocity.runtime.resource.Resource;   
  7. import org.apache.velocity.runtime.resource.loader.ResourceLoader;   
  8. public class MyResourceLoader extends ResourceLoader {   
  9.     @Override  
  10.     public long getLastModified(Resource arg0) {   
  11.         // TODO Auto-generated method stub   
  12.         return 0;   
  13.     }   
  14.     @Override  
  15.     public InputStream getResourceStream(String arg0)   
  16.             throws ResourceNotFoundException {   
  17.         InputStream result = null;   
  18.         if (arg0 == null || arg0.length() == 0) {   
  19.             throw new ResourceNotFoundException(   
  20.                     “模板没有被定义~!”);   
  21.         }   
  22.         result = new ByteArrayInputStream(arg0.getBytes());   
  23.         return result;   
  24.     }   
  25.     @Override  
  26.     public void init(ExtendedProperties arg0) {   
  27.         // TODO Auto-generated method stub   
  28.     }   
  29.     @Override  
  30.     public boolean isSourceModified(Resource arg0) {   
  31.         // TODO Auto-generated method stub   
  32.         return false;   
  33.     }   
  34. }  

只需实现getResourceStream方法就可以了。

  1. import java.io.StringWriter;   
  2. import java.util.Properties;   
  3. import org.apache.velocity.Template;   
  4. import org.apache.velocity.VelocityContext;   
  5. import org.apache.velocity.app.VelocityEngine;   
  6. public class Simple2 {   
  7.     /**
  8.      * 入门,自定义资源加载器  
  9.      */  
  10.     public static void main(String[] args) {   
  11.         // 创建引擎   
  12.         VelocityEngine ve=new VelocityEngine();   
  13.         Properties   p=new   Properties();   
  14.         // 此处需要注意srl.resource.loader.class的前缀必须与srl.resource.loader一致    
  15.         // resource.loader是关键字,srl是自定义的resource loader名字,可以更改   
  16.         p.put(“resource.loader”,“srl”);   
  17.         p.put(“srl.resource.loader.class”,“test.velocity.MyResourceLoader”);   
  18.         try {   
  19.             //进行初始化操作   
  20.             ve.init(p);   
  21.             //加载模板,设定模板编码   
  22.             Template t=ve.getTemplate(“你好 $name !\r\n$project project.”,“gbk”);   
  23.             //设置初始化数据   
  24.             VelocityContext context = new VelocityContext();   
  25.             context.put(“name”“张三”);   
  26.             context.put(“project”“Jakarta”);   
  27.             //设置输出   
  28.             StringWriter writer = new StringWriter();   
  29.             //将环境数据转化输出   
  30.             t.merge(context, writer);   
  31.             //简化操作   
  32.             //ve.mergeTemplate(“test/velocity/simple1.vm”, ”gbk”, context, writer );   
  33.             System.out.println(writer.toString());   
  34.         } catch (Exception e) {   
  35.             e.printStackTrace();   
  36.         }   
  37.     }   
  38. }  

主要就是 p.put(“resource.loader”,”srl”);
p.put(“srl.resource.loader.class”,”test.velocity.MyResourceLoader”);
这两行,来定义资源加载器
这样Template t=ve.getTemplate(“你好 $name !\r\n$project project.”,”gbk”);
模板中的内容我们就可以通过数据库读取出来。

方法三:
有时候我们自定义的ResourceLoader中需要引用Spring托管的Bean,这时候怎么办呢?通过查看Velocity源码发现可以通过如下方式实现:
首先,我们自定义一个ResourceLoader
  1. package com.test.template;   
  2.     
  3. import java.io.ByteArrayInputStream;   
  4. import java.io.InputStream;   
  5. import java.io.UnsupportedEncodingException;   
  6.     
  7. import org.apache.commons.collections.ExtendedProperties;   
  8. import org.apache.log4j.Logger;   
  9. import org.apache.velocity.exception.ResourceNotFoundException;   
  10. import org.apache.velocity.runtime.resource.Resource;   
  11. import org.apache.velocity.runtime.resource.loader.ResourceLoader;   
  12. import org.springframework.stereotype.Service;   
  13.     
  14. /**   
  15.  * @author wangbaocai.cn   
  16.  *   
  17.  */   
  18. @Service (“byteResourceLoader” )   
  19. public class ByteResourceLoader extends ResourceLoader {   
  20.     
  21.        private static final Logger logger = Logger  
  22.                   . getLogger(ByteResourceLoader. class);   
  23.     
  24.        @Override   
  25.        public void init(ExtendedProperties configuration) {   
  26.              // TODO Auto-generated method stub   
  27.       }   
  28.     
  29.        /**   
  30.        * 将消息本体转换成输入流   
  31.        */   
  32.        @Override   
  33.        public InputStream getResourceStream(String message)   
  34.                    throws ResourceNotFoundException {   
  35.                
  36.              if (message== null){   
  37.                    throw new ResourceNotFoundException( ”message is null”);   
  38.             }   
  39.              try {   
  40.                    return new ByteArrayInputStream(message.getBytes(“utf-8″ ));   
  41.             } catch (UnsupportedEncodingException e) {   
  42.                    logger .error(e);   
  43.             }   
  44.              return null ;   
  45.       }   
  46.     
  47.        @Override   
  48.        public boolean isSourceModified(Resource resource) {   
  49.              // TODO Auto-generated method stub   
  50.              return false ;   
  51.       }   
  52.     
  53.        @Override   
  54.        public long getLastModified(Resource resource) {   
  55.              // TODO Auto-generated method stub   
  56.              return 0;   
  57.       }   
  58. }  
VelocityEngine使用单例模式,加载Spring托管的ResourceLoader方式如下:
  1. package com.neusoft.saca.emm.push.template;   
  2.     
  3. import java.io.IOException;   
  4. import java.io.StringWriter;   
  5. import java.io.Writer;   
  6. import java.util.Map;   
  7.     
  8. import org.apache.velocity.Template;   
  9. import org.apache.velocity.VelocityContext;   
  10. import org.apache.velocity.app.Velocity;   
  11. import org.apache.velocity.app.VelocityEngine;   
  12. import org.apache.velocity.runtime.resource.loader.ResourceLoader;   
  13. import org.springframework.beans.factory.InitializingBean;   
  14. import org.springframework.beans.factory.annotation.Autowired;   
  15. import org.springframework.stereotype.Service;   
  16.     
  17. /**   
  18.  * 根据模板生成内容   
  19.  * @author wangbaocai.cn   
  20.  * @param <K>  
  21.  * @param <K>  
  22.  * @param <V>  
  23.  * @param <V>  
  24.  *   
  25.  */   
  26. @Service   
  27. public class TemplateProcessor<K, V>  implements InitializingBean{   
  28.     
  29.        @Autowired   
  30.       ResourceLoader resourceLoader ;   
  31.          
  32.        /**   
  33.        * 根据模板template和map<key,value>生成内容   
  34.        * 根据map中的key,value值替换template中对应的占位符   
  35.        * @param template   
  36.        * @param map   
  37.        * @return   
  38.        * @throws IOException   
  39.        */   
  40.        public String process(String template, Map<K, V> map) throws IOException {   
  41.                
  42.              if (map == null || map.size()==0){   
  43.                    return template;   
  44.             }   
  45.                
  46.              // 取得模板   
  47.             Template t = Velocity. getTemplate(template, ”utf-8″ );   
  48.     
  49.              // 设置初始化数据   
  50.             VelocityContext context = new VelocityContext();   
  51.                
  52.              // 替换模板占位符   
  53.              for (Map.Entry<K, V> entry : map.entrySet()) {   
  54.                   context.put((String) entry.getKey(), (String) entry.getValue());   
  55.             }   
  56.     
  57.              // 设置输出   
  58.             Writer writer = new StringWriter();   
  59.     
  60.              // 将环境数据转化输出   
  61.             t.merge(context, writer);   
  62.     
  63.              // 关闭writer   
  64.              try {   
  65.                   writer.close();   
  66.             } catch (IOException e1) {   
  67.                    throw e1;   
  68.             }   
  69.              return writer.toString();   
  70.       }   
  71.     
  72.        @Override   
  73.        public void afterPropertiesSet() throws Exception {   
  74.              Velocity. setProperty(VelocityEngine. RESOURCE_LOADER, ”byte” );   
  75.              Velocity. setProperty(“byte.resource.loader.instance” , resourceLoader );   
  76.              Velocity. init();   
  77.       }   
  78. }   
  79.    
 
通过如下方式进行调用
  1. @Autowired   
  2.      TemplateProcessor<String, String> templateProcessor ;   
  3.   
  4.      Map<String, String> templateMap = new HashMap<String, String>();   
  5.   
  6.      // TODO 构造要替换的模板内容   
  7.      // map.put(“”, ”");   
  8.   
  9.      String xmlMsg = null ;   
  10.      try {   
  11.            xmlMsg = templateProcessor  
  12.                              .process(message.getXmlMsg(), templateMap);   
  13.            logger .info(“Template process success!Template content is ”   
  14.                              + xmlMsg);   
  15.      } catch (IOException e1) {   
  16.            logger .error(“Template process error: ” + e1);   
  17.      }  
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>