FreeMarker是一个“模板引擎”,通过对模板的填充实现输出,第一个实例:
    // 进行全局配置
    Configuration conf = new Configuration();
    conf.setDirectoryForTemplateLoading(new File("F:/dev/freemarker-2.3.15/templates"));
    conf.setObjectWrapper(new DefaultObjectWrapper());

    // 创建数据模型
    Map root = new HashMap();
    root.put("user", "天天向上");
    Map prod = new HashMap();
    prod.put("url", "http://www.sina.com.cn");
    prod.put("name", "sina");
    root.put("prod", prod);
    
    // 获得模板
    Template temp = conf.getTemplate("prod.ftl");
    Writer out = new OutputStreamWriter(System.out);
    temp.process(root, out);
    out.flush();
模板文件如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
    <TITLE> New Document </TITLE>
</HEAD>

<BODY>
    <h1>Welcome ${user}!</h1>
    <p>Our Super:
    <a href="${prod.url}">${prod.name}</a>!
</BODY>
</HTML>
得到的控制台输出:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
    <TITLE> New Document </TITLE>
</HEAD>

<BODY>
    <h1>Welcome 天天向上!</h1>
    <p>Our Super:
    <a href="http://www.sina.com.cn">sina</a>!
</BODY>
</HTML>
 
以字符的形式输入和输出:
StringBuffer sbTemp = new StringBuffer(128);
    sbTemp.append("<table>\n<#list tempVOList as vo><tr>\n");
    sbTemp.append("<td>${vo.str}</td><td>${vo.intValue}</td>");
    sbTemp.append("<td>${vo.bool?string('是','否')}</td><td>${vo.time}</td>");
    sbTemp.append("</tr>\n</#list></table>");
    
    List list = new ArrayList();
    list.add(new TmpVO());
    list.add(new TmpVO());
    list.add(new TmpVO());
    Map rootMap = new HashMap();
    rootMap.put("tempVOList", list);
    
    Configuration conf = new Configuration();
    conf.setNumberFormat("0.#");
    conf.setDateTimeFormat("yyyy-MM-dd HH:mm");
    Template temp = new Template("tblHtml", new StringReader(sbTemp.toString()), conf);

    StringWriter sw = new StringWriter();
    temp.process(rootMap, sw);
    System.out.println(sw.toString());
 
值得注意的是,上面模板中,对于boolean对象的输出采用的格式是“${vo.bool?string('是','否')}”,直接采用“${vo.bool}”将导致异常;同时对对象类型的数据如日期时间等采用形如“${vo.str}”的方式输出内容时必须保证值不为空,否则将抛出空指针异常。
其中TmpVO对象的代码如下:
public class TmpVO {
  String str;
  int intValue;
  boolean bool;
  Timestamp time;

  public String getStr() {
    return str;
  }

  public int getIntValue() {
    return intValue;
  }

  public boolean isBool() {
    return bool;
  }

  public Timestamp getTime() {
    return time;
  }

  public TmpVO() {
    this.str = "string value";
    this.intValue = 1200;
    this.bool = true;
    this.time = Timestamp.valueOf("2009-3-21 12:12:12");
  }
}
输出:
<table>
<tr>
<td>string value</td><td>1200</td><td></td><td>2009-03-21 12:12</td></tr>
<tr>
<td>string value</td><td>1200</td><td></td><td>2009-03-21 12:12</td></tr>
<tr>
<td>string value</td><td>1200</td><td></td><td>2009-03-21 12:12</td></tr>
</table>
 
对于上面模板字符串比较复杂的情况,也可以如下改进:
StringTemplateLoader strLoader = new StringTemplateLoader();
    strLoader.putTemplate("tdHtml", "<td>${vo.str}</td><td>${vo.time}</td>");
    strLoader.putTemplate("trHtml", "<#list tempVOList as vo>\n<tr><#include 'tdHtml'/></tr>\n</#list>");
    strLoader.putTemplate("tblHtml", "<table><#include 'trHtml'></table>");
    
    List list = new ArrayList();
    list.add(new TmpVO());
    list.add(new TmpVO());
    list.add(new TmpVO());
    Map rootMap = new HashMap();
    rootMap.put("tempVOList", list);

    Configuration conf = new Configuration();
    conf.setNumberFormat("0.#");
    conf.setDateTimeFormat("yyyy-MM-dd HH:mm");
    conf.setTemplateLoader(strLoader);

    StringWriter sw = new StringWriter();
    Template temp = conf.getTemplate("tblHtml");
    temp.process(rootMap, sw);
    System.out.println(sw.toString());
对应的输出为:
<table><tr><td>string value</td><td>2009-03-21 12:12</td></tr>
<tr><td>string value</td><td>2009-03-21 12:12</td></tr>
<tr><td>string value</td><td>2009-03-21 12:12</td></tr>
</table>