方法变量通常是实现了 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) { Maproot=new HashMap (); root.put("length", new StringLengthMethod()); FreeMarkertUtil.processTemplate("src/templates","demo01.ftl", "UTF-8", root, new OutputStreamWriter(System.out)); } }
模板文件demo01.ftl如下:
${length("取字符串长度")}