`
Mydwr
  • 浏览: 27871 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

freemarker中实现自定义标签

阅读更多
  1. import  java.io.IOException;   
  2.   import  java.io.Writer;   
  3.   import  java.util.Iterator;   
  4.   import  java.util.Map;   
  5.   
  6.   import  freemarker .core.Environment;   
  7. import  freemarker .template.SimpleNumber;   
  8. import  freemarker .template.TemplateBooleanModel;   
  9. import  freemarker .template.TemplateDirectiveBody;   
  10. import  freemarker .template.TemplateDirectiveModel ;   
  11. import  freemarker .template.TemplateException;   
  12. import  freemarker .template.TemplateModel;   
  13. import  freemarker .template.TemplateModelException;   
  14. import  freemarker .template.TemplateNumberModel;   
  15.   
  16. /**  
  17.  * FreeMarker  自定义标签实现重复输出内容体。  
  18.  *   
  19.  *   
  20.  * 参数:  
  21.  * count: 重复的次数,必须的且非负整数。  
  22.  * hr: 设置是否输出HTML标签 "hr" 元素. Boolean. 可选的默认为fals.  
  23.  *   
  24.  *   
  25.  * 循环变量: 只有一个,可选的. 从1开始。  
  26.  *   
  27.  *   
  28.  */   
  29. public   class  RepeatDirective  implements  TemplateDirectiveModel  {   
  30.   
  31.      private   static   final  String PARAM_NAME_COUNT =  "count" ;   
  32.      private   static   final  String PARAM_NAME_HR =  "hr" ;   
  33.   
  34.      public   void  execute(Environment env, Map params, TemplateModel[] loopVars,   
  35.             TemplateDirectiveBody body)  throws  TemplateException, IOException {   
  36.   
  37.          // ---------------------------------------------------------------------   
  38.          // 处理参数   
  39.   
  40.          int  countParam =  0 ;   
  41.          boolean  countParamSet =  false ;   
  42.          boolean  hrParam =  false ;   
  43.   
  44.         Iterator paramIter = params.entrySet().iterator();   
  45.          while  (paramIter.hasNext()) {   
  46.             Map.Entry ent = (Map.Entry) paramIter.next();   
  47.   
  48.             String paramName = (String) ent.getKey();   
  49.             TemplateModel paramValue = (TemplateModel) ent.getValue();   
  50.   
  51.              if  (paramName.equals(PARAM_NAME_COUNT)) {   
  52.                  if  (!(paramValue  instanceof  TemplateNumberModel)) {   
  53.                      throw   new  TemplateModelException( "The \""  + PARAM_NAME_HR   
  54.                             +  "\" parameter "  +  "must be a number." );   
  55.                 }   
  56.                 countParam = ((TemplateNumberModel) paramValue).getAsNumber()   
  57.                         .intValue();   
  58.                 countParamSet =  true ;   
  59.                  if  (countParam <  0 ) {   
  60.                      throw   new  TemplateModelException( "The \""  + PARAM_NAME_HR   
  61.                             +  "\" parameter "  +  "can't be negative." );   
  62.                 }   
  63.             }  else   if  (paramName.equals(PARAM_NAME_HR)) {   
  64.                  if  (!(paramValue  instanceof  TemplateBooleanModel)) {   
  65.                      throw   new  TemplateModelException( "The \""  + PARAM_NAME_HR   
  66.                             +  "\" parameter "  +  "must be a boolean." );   
  67.                 }   
  68.                 hrParam = ((TemplateBooleanModel) paramValue).getAsBoolean();   
  69.             }  else  {   
  70.                  throw   new  TemplateModelException( "Unsupported parameter: "   
  71.                         + paramName);   
  72.             }   
  73.         }   
  74.          if  (!countParamSet) {   
  75.              throw   new  TemplateModelException( "The required \""   
  76.                     + PARAM_NAME_COUNT +  "\" paramter"  +  "is missing." );   
  77.         }   
  78.   
  79.          if  (loopVars.length >  1 ) {   
  80.              throw   new  TemplateModelException(   
  81.                      "At most one loop variable is allowed." );   
  82.         }   
  83.   
  84.          // Yeah, it was long and boring...   
  85.   
  86.          // ---------------------------------------------------------------------   
  87.          // 真正开始处理输出内容   
  88.   
  89.         Writer out = env.getOut();   
  90.          if  (body !=  null ) {   
  91.              for  ( int  i =  0 ; i < countParam; i++) {   
  92.                  // 输出  <hr> 如果 参数hr 设置为true   
  93.                  if  (hrParam && i !=  0 ) {   
  94.                     out.write( "<hr>" );   
  95.                 }   
  96.   
  97.                  // 设置循环变量   
  98.                  if  (loopVars.length >  0 ) {   
  99.                     loopVars[ 0 ] =  new  SimpleNumber(i +  1 );   
  100.                 }   
  101.   
  102.                  // 执行标签内容(same as <#nested> in FTL).    
  103.                 body.render(env.getOut());   
  104.             }   
  105.         }   
  106.     }   
  107.   
  108. }  
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;

 

import freemarker .core.Environment; import freemarker .template.SimpleNumber; import freemarker .template.TemplateBooleanModel; import freemarker .template.TemplateDirectiveBody; import freemarker .template.TemplateDirectiveModel ; import freemarker .template.TemplateException; import freemarker .template.TemplateModel; import freemarker .template.TemplateModelException; import freemarker .template.TemplateNumberModel;

/** * FreeMarker 自定义标签实现重复输出内容体。 * * * 参数: * count: 重复的次数,必须的且非负整数。 * hr: 设置是否输出HTML标签 "hr" 元素. Boolean. 可选的默认为fals. * * * 循环变量: 只有一个,可选的. 从1开始。 * * */ public class RepeatDirective implements TemplateDirectiveModel {

private static final String PARAM_NAME_COUNT = "count"; private static final String PARAM_NAME_HR = "hr";

public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {

// --------------------------------------------------------------------- // 处理参数

int countParam = 0; boolean countParamSet = false; boolean hrParam = false;

Iterator paramIter = params.entrySet().iterator(); while (paramIter.hasNext()) { Map.Entry ent = (Map.Entry) paramIter.next();

String paramName = (String) ent.getKey(); TemplateModel paramValue = (TemplateModel) ent.getValue();

if (paramName.equals(PARAM_NAME_COUNT)) { if (!(paramValue instanceof TemplateNumberModel)) { throw new TemplateModelException("The \"" + PARAM_NAME_HR + "\" parameter " + "must be a number."); } countParam = ((TemplateNumberModel) paramValue).getAsNumber() .intValue(); countParamSet = true; if (countParam < 0) { throw new TemplateModelException("The \"" + PARAM_NAME_HR + "\" parameter " + "can't be negative."); } } else if (paramName.equals(PARAM_NAME_HR)) { if (!(paramValue instanceof TemplateBooleanModel)) { throw new TemplateModelException("The \"" + PARAM_NAME_HR + "\" parameter " + "must be a boolean."); } hrParam = ((TemplateBooleanModel) paramValue).getAsBoolean(); } else { throw new TemplateModelException("Unsupported parameter: " + paramName); } } if (!countParamSet) { throw new TemplateModelException("The required \"" + PARAM_NAME_COUNT + "\" paramter" + "is missing."); }

if (loopVars.length > 1) { throw new TemplateModelException( "At most one loop variable is allowed."); }

// Yeah, it was long and boring...

// --------------------------------------------------------------------- // 真正开始处理输出内容

Writer out = env.getOut(); if (body != null) { for (int i = 0; i < countParam; i++) { // 输出  <hr> 如果 参数hr 设置为true if (hrParam && i != 0) { out.write("<hr>"); }

// 设置循环变量 if (loopVars.length > 0) { loopVars[0] = new SimpleNumber(i + 1); }

// 执行标签内容(same as <#nested> in FTL). body.render(env.getOut()); } } }

}

 

Java代码
  1. import  java.io.File;   
  2. import  java.io.IOException;   
  3. import  java.io.Writer;   
  4. import  java.util.Map;   
  5.   
  6. import  freemarker .template.Configuration;   
  7. import  freemarker .template.DefaultObjectWrapper;   
  8. import  freemarker .template.Template;   
  9. import  freemarker .template.TemplateException;   
  10.   
  11. /**  
  12.  *   
  13.  * 模板工具类  
  14.  */   
  15. public   class  FreeMarkertUtil {   
  16.      /**  
  17.      * @param templatePath 模板文件存放目录   
  18.      * @param templateName 模板文件名称   
  19.      * @param root 数据模型根对象  
  20.      * @param templateEncoding 模板文件的编码方式  
  21.      * @param out 输出流  
  22.      */   
  23.      public   static   void  processTemplate(String templatePath, String templateName, String templateEncoding, Map<?,?> root, Writer out){   
  24.          try  {   
  25.             Configuration config= new  Configuration();   
  26.             File file= new  File(templatePath);   
  27.              //设置要解析的模板所在的目录,并加载模板文件   
  28.             config.setDirectoryForTemplateLoading(file);   
  29.              //设置包装器,并将对象包装为数据模型   
  30.             config.setObjectWrapper( new  DefaultObjectWrapper());   
  31.                
  32.              //获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致   
  33.             Template template=config.getTemplate(templateName,templateEncoding);   
  34.              //合并数据模型与模板   
  35.                
  36.             template.process(root, out);   
  37.             out.flush();   
  38.             out.close();   
  39.         }  catch  (IOException e) {   
  40.             e.printStackTrace();   
  41.         } catch  (TemplateException e) {   
  42.             e.printStackTrace();   
  43.         }   
  44.            
  45.     }    
  46. }  
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;

 

import freemarker .template.Configuration; import freemarker .template.DefaultObjectWrapper; import freemarker .template.Template; import freemarker .template.TemplateException;

/** * * 模板工具类 */ public class FreeMarkertUtil { /** * @param templatePath 模板文件存放目录 * @param templateName 模板文件名称 * @param root 数据模型根对象 * @param templateEncoding 模板文件的编码方式 * @param out 输出流 */ public static void processTemplate(String templatePath, String templateName, String templateEncoding, Map<?,?> root, Writer out){ try { Configuration config=new Configuration(); File file=new File(templatePath); //设置要解析的模板所在的目录,并加载模板文件 config.setDirectoryForTemplateLoading(file); //设置包装器,并将对象包装为数据模型 config.setObjectWrapper(new DefaultObjectWrapper());

//获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致 Template template=config.getTemplate(templateName,templateEncoding); //合并数据模型与模板

    template.process(root, out);     out.flush();     out.close(); } catch (IOException e) { e.printStackTrace(); }catch (TemplateException e) { e.printStackTrace(); }

} }

 

 

Java代码
  1. import  java.io.OutputStreamWriter;   
  2. import  java.util.HashMap;   
  3. import  java.util.Map;   
  4.   
  5. /**  
  6.  *   
  7.  * 客户端测试模板输入类  
  8.  */   
  9. public   class  RepeatTest {   
  10.      public   static   void  main(String[] args) {   
  11.         Map<String,Object> root= new  HashMap<String, Object>();   
  12.   
  13.         root.put( "repeat" new  RepeatDirective());   
  14.            
  15.         FreeMarkertUtil.processTemplate( "src/templates" , "repeat.ftl" "UTF-8" , root,  new  OutputStreamWriter(System.out));   
  16.            
  17.     }   
  18. }  
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;

 

/** * * 客户端测试模板输入类 */ public class RepeatTest { public static void main(String[] args) { Map<String,Object> root=new HashMap<String, Object>();

root.put("repeat", new RepeatDirective());

FreeMarkertUtil.processTemplate("src/templates","repeat.ftl", "UTF-8", root, new OutputStreamWriter(System.out));

} }

 

 模板文件repeat.ftl如下:

 

Java代码
  1. <#assign x =  1 >   
  2.   
  3. 一个参数:   
  4. < @repeat  count= 4 >   
  5.   Test ${x}   
  6.   <#assign x = x +  1 >   
  7. </ @repeat >   
  8.   
  9. 二个参数:   
  10. < @repeat  count= 3  hr= true >   
  11.   Test   
  12. </ @repeat >   
  13.   
  14. 循环变量:   
  15. < @repeat  count= 3 ; cnt>   
  16.   ${cnt}. Test   
  17. </ @repeat >    
<#assign x = 1>

 

一个参数: <@repeat count=4>   Test ${x}   <#assign x = x + 1> </@repeat>

二个参数: <@repeat count=3 hr=true>   Test </@repeat>

循环变量: <@repeat count=3; cnt>   ${cnt}. Test </@repeat>  

 

 输出结果:

Java代码
  1. 一个参数:   
  2.   Test  1   
  3.   Test  2   
  4.   Test  3   
  5.   Test  4   
  6.   
  7. 二个参数:   
  8.   Test   
  9. <hr>  Test   
  10. <hr>  Test   
  11.   
  12. 循环变量:   
  13.    1 . Test   
  14.    2 . Test   
  15.    3 . Test
分享到:
评论

相关推荐

    实现通过jfinal框架自动扫描freemarker的自定义标签.zip

    在jfinal的基础上,实现freemarker自定义标签的自动扫描和注册,本资源包不含jfinal框架,需在已有框架的基础上添加包中的代码,如需jfinal框架请自行到官网下载

    在struts2的freemarker模板中扩展struts标签

    众所周知,struts2宣称freemarker模板中不再支持自定义标签,但如果工程UI仅用freemarker模板可以通过扩展struts标签简单实现,不是采用官方不推荐的配置JspSupportServlet实现的!内付详细说明及范例,此方法仅为团队...

    freemarker实现自动补齐字符串

    freemarker实现自动补齐字符串。通过ftl模版文件(ftl文件为freemarker模版文件)的自定义标签实现自动补齐字符串。代码稍作修改便可左补齐右补齐左右补齐,可自定义设置补齐的字符串。测试通过java文件调用ftl文件...

    超完整FreeMarker中文教程,代码

    什么是FreeMarker? ................................................................................................. 7 我们应该阅读什么内容? .............................................................

    freemarker总结

    上面的代码中的逻辑表达式用括号括起来主要是因为里面有&gt;符号,由于FreeMarker会将&gt;符号当成标签的结束字符,可能导致程序出错,为了避免这种情况,我们应该在凡是出现这些符号的地方都使用括号. Pythons are ...

    非常好的mybatisplus项目资源,分享出来.zip

    | ├── FreeMarker -- 自定义FreeMarker标签 │ ├── resources | ├── mapper -- SQL对应的XML文件 | ├── templates -- FreeMarker模版 │ ├── webapp | ├── statics -- 静态资源 | ├── upload -...

    jeecms-src.rar_com.jeec_freemarker_freemarker struts2_单点登录

    强大、灵活的标签,用户自定义显示内容和显示方式 在设计上自身预先做了搜索引擎优化,增强对搜索引擎的友好性 采用伪静态页面技术,可自定义路径结构,无需urlrewrite 轻松建设大规模网站,可通过次级域名建立子...

    SpringBoot集成MyBatisPlus

    | ├── FreeMarker -- 自定义FreeMarker标签 │ ├── resources | ├── mapper -- SQL对应的XML文件 | ├── templates -- FreeMarker模版 │ ├── webapp | ├── statics -- 静态资源 | ├── upload -...

    Struts2 标签库

    Struts2允许在页面中使用自定义组件,这完全能满足项目中页面显示复杂,多变的需求。 005 Struts2的标签库有一个巨大的改进之处,struts2标签库的标签不依赖于任何表现层技术,也就是说strtus2提供了大部分标签,...

    hibernate3+struts2+spring2+freemarker 主流技术架构 实例

    • 强大、灵活的标签,用户自定义显示内容和显示方式 • 在设计上自身预先做了搜索引擎优化,增强对搜索引擎的友好性 • 采用伪静态结合页面缓存技术,可自定义路径结构,无需urlrewrite • 轻松建设大规模网站,可...

    jeecmsv2.3.2 内容管理系统 (hibernate3+struts2+spring2+freemarker)

    · 强大、灵活的标签,用户自定义显示内容和显示方式 · 在设计上自身预先做了搜索引擎优化,增强对搜索引擎的友好性 · 采用伪静态结合页面缓存技术,可自定义路径结构,无需urlrewrite · 轻松建设大规模网站,可...

    struts2 学习例子

    非UI标签可分为流程控制标签(包括用于实现分支、循环等流程控制的标签)和数据访问标签(主要包括用户输出ValueStack中的值,完成国际化等功能的) (3)ajax标签 3.Struts2标签使用前的准备: (1)在要使用标签...

    FreeMarker 手册

    4.1 自定义指令 ................................................................................................ 45 4.2 在模板中定义变量 ...................................................................

    struts2讲义_吴峻申

    5.7 Struts2自定义标签实现图形验证功能 121 第6章 Struts2非JSP视图技术 125 6.1 velocity视图技术使用介绍 125 6.2 freemarker视图技术使用介绍 128 6.3 JasperReports报表视图技术使用介绍 130 第7章 Struts2类型...

    Thymeleaf中文参考手册_3.0.5版

    Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP .1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的...

    基于SpringMVC的一个web框架

    工具类数据校验 jsp自定义标签 Spring自定义注解 默认requestMapping 1.1.2 代码生成器 1.1.3 首页修改 dateformat.js 时间参数转换 SpringMVC配置文件集中 快递参数接口 1.1.4 des加解密字符串和文件 1.1.5 redis...

    基于Spring MVC的web框架 1.1.11

    工具类数据校验 jsp自定义标签 Spring自定义注解 默认requestMapping 1.1.2 代码生成器 1.1.3 首页修改 dateformat.js 时间参数转换 SpringMVC配置文件集中 快递参数接口 1.1.4 des加解密字符串和文件 1.1.5 redis...

    一个可以直接运行的基于SpringMVC的web框架1.1.12

    工具类数据校验 jsp自定义标签 Spring自定义注解 默认requestMapping 1.1.2 代码生成器 1.1.3 首页修改 dateformat.js 时间参数转换 SpringMVC配置文件集中 快递参数接口 1.1.4 des加解密字符串和文件 1.1.5 redis...

    可以直接运行的基于SpringMVC的web框架示例,也可以直接当公司框架

    工具类数据校验 jsp自定义标签 Spring自定义注解 默认requestMapping 1.1.2 代码生成器 1.1.3 首页修改 dateformat.js 时间参数转换 SpringMVC配置文件集中 快递参数接口 1.1.4 des加解密字符串和文件 1.1.5 redis...

    深入浅出Struts2(附源码)

    作者处处从实战出发,在丰富的示例中直观地探讨了许多实用的技术,如数据类型转换、文件上传和下载、提高Struts 2应用的安全性、调试与性能分析、FreeMarker、Velocity、Ajax,等等。跟随作者一道深入Struts 2,聆听...

Global site tag (gtag.js) - Google Analytics