`
osacar
  • 浏览: 209987 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

freemarker中实现自定义标签(包含处理参数以及循环变量)

阅读更多
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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics