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.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.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如下:
- <#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>
<#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>
输出结果:
- 一个参数:
- Test 1
- Test 2
- Test 3
- Test 4
- 二个参数:
- Test
- <hr> Test
- <hr> Test
- 循环变量:
- 1. Test
- 2. Test
- 3. Test