以前使用模板都是加載模板文件(*.ftl文件),這次處理的文件是保存在數據庫的字符串,在新版freemarker中增加了StringTemplateLoader類,沒錯這個就是字符串轉成模板,以前我們還需要自己繼承這個TemplateLoader類重寫(當然需要再改造的可以當我沒說)
好,廢話不多說
提供一下pom.xml,用的版本號
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
ok,你們一定問,如果項目已經有點舊,不能隨意升級版本號怎麼辦,那自己寫一個把,我順便提供一下源碼
import java.io.Reader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.utility.StringUtil;
public class StringTemplateLoader implements TemplateLoader {
private final Map<String, StringTemplateSource> templates = new HashMap<String, StringTemplateSource>();
public void putTemplate(String name, String templateContent) {
putTemplate(name, templateContent, System.currentTimeMillis());
}
public void putTemplate(String name, String templateContent, long lastModified) {
templates.put(name, new StringTemplateSource(name, templateContent, lastModified));
}
public boolean removeTemplate(String name) {
return templates.remove(name) != null;
}
public void closeTemplateSource(Object templateSource) {
}
public Object findTemplateSource(String name) {
return templates.get(name);
}
public long getLastModified(Object templateSource) {
return ((StringTemplateSource) templateSource).lastModified;
}
public Reader getReader(Object templateSource, String encoding) {
return new StringReader(((StringTemplateSource) templateSource).templateContent);
}
private static class StringTemplateSource {
private final String name;
private final String templateContent;
private final long lastModified;
StringTemplateSource(String name, String templateContent, long lastModified) {
if (name == null) {
throw new IllegalArgumentException("name == null");
}
if (templateContent == null) {
throw new IllegalArgumentException("source == null");
}
if (lastModified < -1L) {
throw new IllegalArgumentException("lastModified < -1L");
}
this.name = name;
this.templateContent = templateContent;
this.lastModified = lastModified;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
StringTemplateSource other = (StringTemplateSource) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return name;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(TemplateLoaderUtils.getClassNameForToString(this));
sb.append("(Map { ");
int cnt = 0;
for (String name : templates.keySet()) {
cnt++;
if (cnt != 1) {
sb.append(", ");
}
if (cnt > 10) {
sb.append("...");
break;
}
sb.append(StringUtil.jQuote(name));
sb.append("=...");
}
if (cnt != 0) {
sb.append(' ');
}
sb.append("})");
return sb.toString();
}
}
自己建一個就好,也方便重寫
然後怎麼用呢,我給出測試類你們
public static void main(String[] args) throws Exception {
Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
cfg.setCacheStorage(new freemarker.cache.NullCacheStorage());
StringTemplateLoader stl = new StringTemplateLoader();
//單個測試
//stl.putTemplate("temp", "你好:${user}");
//嵌套測試
stl.putTemplate("greetTemplate", "<#macro greet>${user}</#macro>");
stl.putTemplate("myTemplate", "<#include \"greetTemplate\"><@greet/> World!");
cfg.setTemplateLoader(stl);
Template template = cfg.getTemplate("myTemplate","utf-8");
Map<String,Object> root = new HashMap<String,Object>();
root.put("user", "yemon");
StringWriter writer = new StringWriter();
template.process(root, writer);
System.out.println(writer.toString());
}
這裏用到單個和嵌入模板(include 語句),方便案例測試
常見問題
嵌入模板有什麼用?
如果cms,header和footer頁一般是一樣的,這裏可以通用,沒必要多設置,這樣可以統一打理
測試方法好像打印debug日誌,能不能消除?
能,在log4j日誌配置文件配置就好?
#設置關閉freemarker日誌
log4j.logger.freemarker=ERROR
這個日誌文件在哪裏?
如果你是spring項目,就是項目下resources的log4j.properties,最底下加進上一句就可以了