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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Spring Boot 使用 Freemarker 自定义标签,可以通过以下步骤实现: 1. 创建一个自定义标签类,继承 `freemarker.template.TemplateDirectiveModel` 接口,并实现的 `execute` 方法,该方法用于处理自定义标签的逻辑。 ```java @Component public class CustomTagDirective implements TemplateDirectiveModel { @Autowired private UserService userService; // 举例注入一个服务类 @Override public void execute(Environment environment, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { // 处理自定义标签逻辑,可以使用 environment、params、body 等参数 String userId = params.get("userId").toString(); User user = userService.getUserById(userId); environment.getOut().write(user.getName()); } } ``` 2. 在 Spring Boot 的配置文件注册自定义标签类。 ```java @Configuration public class FreemarkerConfig { @Autowired private CustomTagDirective customTagDirective; @Bean public FreeMarkerConfigurer freeMarkerConfigurer() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setTemplateLoaderPath("classpath:/templates"); Map<String, Object> variables = new HashMap<>(); variables.put("customTag", customTagDirective); configurer.setFreemarkerVariables(variables); return configurer; } } ``` 3. 在 Freemarker 模板使用自定义标签。 ```html <#assign userId = "1" /> <@customTag userId=userId /> ``` 在以上代码,我们首先通过 `<#assign>` 定义了一个变量 `userId`,然后通过 `<@customTag>` 调用自定义标签,并将 `userId` 作为参数传入。 这样就可以在 Spring Boot 使用自定义Freemarker 标签了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值