方法变量通常是实现了 TemplateMethodModel 接口的类,该接口有一个方法TemplateModel exec(java.util.List arguments)。当你使用方法表达式 (method call expression)调用一个方法(exec)的时候,实际上是在执行 exec。方法表达式的参数其实就是方法参数的变形。方法的返回值也就是方法表达式的返回值。由于方法接口 TemplateMethodModelEx 继承自TemplateMethodModel 接口,所以方法也可以当作变量一样被放置到 root 中。
例子,实现求字符串的长度。
import java.util.List;
import freemarker.template.SimpleNumber;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
public class StringLengthMethod implements TemplateMethodModel {
public TemplateModel exec(List args) throws TemplateModelException {
if (args.size() != 1) {
throw new TemplateModelException("Wrong arguments");
}
return new SimpleNumber(((String) args.get(0)).length());
}
}
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 ClientTest {
public static void main(String[] args) {
Map<String,Object> root=new HashMap<String, Object>();
root.put("length", new StringLengthMethod());
FreeMarkertUtil.processTemplate("src/templates","demo01.ftl", "UTF-8", root, new OutputStreamWriter(System.out));
}
}
模板文件demo01.ftl如下:
${length("取字符串长度")}