欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

freemarker中实现自定义标签(包含处理参数以及循环变量) 博客分类: Freemarker freemarkerJava 

程序员文章站 2024-03-08 08:10:03
...
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());    
            }    
        }    
    }    
   
}   


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();    
        }    
            
    }     
}   


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));    
            
    }    
}   
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代码
<#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代码
一个参数:   
  Test 1  
  Test 2  
  Test 3  
  Test 4  
  
二个参数:   
  Test   
<hr>  Test   
<hr>  Test   
  
循环变量:   
  1. Test   
  2. Test   
  3. Test
相关标签: freemarker Java