Freemarker自定義指令

Freemarker自定義指令

1.首先需寫一個方法實現TempletedirectiveModel接口。然後重寫裏面的方法

2.在測試類中写明调用方式:Map root= new HashMap(); root.put("myhr", new Instruct());

3.在ftl文件中调用: <@myhr count=1 />

具体代码如下:

實現指令的類:

package freemarker;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateNumberModel;
/**
 * 當從別人那裡傳過來的Map,list不知道裏面是什麽 一般也不知道怎麼處理 使用Iterator迭代,而這裡的參數是以鍵值的形式保存
 * 所以迭代后,就是 鍵 值
 * 自定義指令
 */
       public class Instruct implements TemplateDirectiveModel {
        private static final String PARAM_NAME_COUNT="count";
        private static final String PARAM_NAME_HR="hr";
       //body為指令間的內容  params為參數 loopvars為循環變量 evn可以得到輸出流 進行輸出
        public void execute(Environment evn, Map params, TemplateModel[] loopvars,TemplateDirectiveBody body) throws TemplateException, IOException {
//          TODO Auto-generated method stub
                //處理參數
                 int countParam = 0;
                 boolean countParamSet =false;
                 boolean hrParam =false;

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

                          //得到自定義指令的參數名
                          String parameKey = (String)entry.getKey();

                           //得到自定義指令的參數的值
                        TemplateModel parameValue=(TemplateModel)entry.getValue();

                        countParam=((TemplateNumberModel)parameValue).getAsNumber().intValue();
                        System.out.println("key:"+parameKey+"\tvalue:"+parameValue+"\tloop:"+countParam);
                         countParamSet=true;
                                }


                           Writer writers=evn.getOut();

                           //寫內容
                              System.out.println("寫之前");
                              writers.write("<hr>");
                                  System.out.println("寫之hou");
                              //執行嵌入體部份(和FTL中的<#nested>一樣)
                            //這種情況下,我們不提供一個特殊的writer作為參數
                           System.out.println(body);
                              if(body!=null)
                           //發送內容到body   不解?爲什麽這裡body報null指針異常
                             //指令之間有沒有內容 如果沒有body為null有則不為null
                               body.render(evn.getOut());
                                 else 
                                      System.out.println("body is null");
                                      System.out.println("發送成功");
                           }
}

ftl文件:

  <html>
  <head>
   <title>Hello World</title>
  </head>
  <body>
<#list 1..5 as x>
<@myhr count=x >
"hllow word!"
</@myhr>
</#list>
</body>
</html>

測試類:

public static void main(String[] args){

new Configuration cfg = new Configuration();
//創建調整配置  加載指定模板目錄
cfg.setDirectoryForTemplateLoading(new File("src/"));
//Object_wrapper設置的默認值是ObjectWrapper.DEFALT_ARAPPER.
//如國想改變它,比如改換成ObjectWarpper.EEANS_WRAPPER,那麼可以這樣配置FreeMarker引擎(在其他線程開始之前)

//ObjectWrapper java類封裝Fr eemarker模型 (轉換)
//好像使用默認包裝器不能把自定義java類型轉成TempleModel模型類

cfg.setObjectWrapper(new BeansWrapper());

cfg.setEncoding(Locale.CHINESE, "utf-8");
//cfg.setObjectWrapper(new DepWrapper());
//創建數據模型  用於在模板文件中顯示,名稱必須一致
Map root = new HashMap();
root.put("myhr", new Instruct());

//獲取創建的模板
Template t = obj.getCfg().getTemplate("instruct.ftl");
t.setObjectWrapper(new DefaultObjectWrapper());
Writer out = new OutputStreamWriter(new FileOutputStream("Instruct.html"),"utf-8");//"Test1.html"),"GBK"
//根據模板文件輸出指定格式文件 參數:數據模型,輸出流
t.process(root, out);
System.out.println("Successfull................");

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要自定义一个名为 ListDirective 的 FreeMarker 指令,你需要遵循以下步骤: 1. 创建一个 Java 类来实现指令。这个类应该继承 `freemarker.template.TemplateDirectiveModel` 接口,并且需要实现 `execute()` 方法,该方法会被 FreeMarker 引擎调用来处理指令。 ```java import java.util.Map; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import freemarker.core.Environment; import freemarker.template.*; public class ListDirective implements TemplateDirectiveModel { public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, java.io.IOException { // 在这里编写逻辑来处理指令 // ... } } ``` 2. 在 `execute()` 方法中编写处理逻辑。在这里,你需要解析和验证指令参数,并使用 `TemplateModel` 对象来获取指令所在的模板环境和输出流。你也需要创建一个 `SimpleScalar` 对象来包装列表数据,并将其放入模板环境中。 ```java public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, java.io.IOException { // 解析和验证指令参数 String listName = DirectiveUtils.getRequiredParam(params, "name"); Object listData = DirectiveUtils.getRequiredParam(params, "data"); // 获取模板环境和输出流 Writer out = env.getOut(); PageContext pageContext = (PageContext) env.getCustomAttribute("PageContext"); if (pageContext == null) { throw new JspException("PageContext not found"); } // 创建 SimpleScalar 对象来包装列表数据 SimpleScalar listModel = new SimpleScalar(listData.toString()); // 将 SimpleScalar 对象放入模板环境中 env.setVariable(listName, listModel); // 处理指令内容 if (body != null) { body.render(out); } } ``` 3. 将自定义指令注册到 FreeMarker 引擎中。你可以使用 `Configuration` 对象的 `setSharedVariable()` 方法将指令实例添加到引擎中。 ```java import freemarker.template.Configuration; Configuration cfg = new Configuration(Configuration.VERSION_2_3_30); cfg.setSharedVariable("list", new ListDirective()); ``` 现在,你就可以在模板中使用自定义指令了: ``` <@list name="myList" data=[1, 2, 3]> <#list myList as item> ${item} </#list> </@list> ``` 这将输出: ``` 1 2 3 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值