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));
}
}
模板文件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>
输出结果:
一个参数:
Test 1
Test 2
Test 3
Test 4
二个参数:
Test
<hr> Test
<hr> Test
循环变量:
1. Test
2. Test
3. Test
分享到:
相关推荐
NULL 博文链接:https://zhenghuazhi.iteye.com/blog/1923544
里面 集合了 一个 简单的 Freemarker demo 代码 和一个 freemarker 自定义标签代码
spring mvc freemarker 自定义标签demo spring mvc 通过自定义的标签在jsp页面调用,初学,记录下做个备忘
在jfinal的基础上,实现freemarker自定义标签的自动扫描和注册,本资源包不含jfinal框架,需在已有框架的基础上添加包中的代码,如需jfinal框架请自行到官网下载
freemarker替换变量实例
一个用FTL定义的非常通用数据分页指令,有源码,有使用示例。使用效果图可以参看本人博客中的相关文章:http://blog.csdn.net/qjyong/archive/2009/10/18/4693142.aspx
NULL 博文链接:https://asialee.iteye.com/blog/2062313
Freemarker简介及标签详解大全 Freemarker简介及标签使用说明
freemarker的shiro标签
Spring MVC配置Freemarker全局变量,实现应用全路径
freemarker实现一行两列算法
NULL 博文链接:https://renxin-327666062-qq-com.iteye.com/blog/1532731
访问freemarker标签大全:http://www.web-tag.net/all_16.htm freemarker 标签大全 freemarker 标签大全
赠送jar包:freemarker-2.3.30.jar; 赠送原API文档:freemarker-2.3.30-javadoc.jar; 赠送源代码:freemarker-2.3.30-sources.jar; 赠送Maven依赖信息文件:freemarker-2.3.30.pom; 包含翻译后的API文档:...
freemarker
众所周知,struts2宣称freemarker模板中不再支持自定义标签,但如果工程UI仅用freemarker模板可以通过扩展struts标签简单实现,不是采用官方不推荐的配置JspSupportServlet实现的!内付详细说明及范例,此方法仅为团队...
freemarker实现自动补...通过ftl模版文件(ftl文件为freemarker模版文件)的自定义标签实现自动补齐字符串。代码稍作修改便可左补齐右补齐左右补齐,可自定义设置补齐的字符串。测试通过java文件调用ftl文件显示结果。
SpringBoot_Freemarker生成Word_多个表格+两层嵌套循环; 步骤说明: 1.用Microsoft Office Word打开word原件;将文档中需要动态生成的内容,替换为属性名 ${name} 2.另存为,选择保存类型Word 2003 XML 文档(*....
FreeMarker中文文档.pdf FreeMarker入门必修
Freemarker页面语法 A 概念 最常用的 3 个概念 sequence 序列,对应java 里的list 、数组等非键值对的集合 hash 键值对的集合 namespace 对一个ftl 文件的引用, 利用这个名字可以访问到该ftl 文件的资源 ...