FreeMarker 复习总结

    其实之前做财产险理赔项目时就用过freemarker,但是没有深入研究,后来做easydb监控项目时其实我角色相当于后台架构师,那么在重视业务的同时也要重视并重温一下快要忘记的知识点。

    我发现我有个毛病就是有点过于精细,有点像一叶障目。言归正传:

    首先研究一个技术点时,首要就是从官网文档入手,freemarker 手册:

    https://freemarker.apache.org/   英文版本

    http://freemarker.foofun.cn/index.html     中文版本

    还是推荐看英文版,毕竟可以练习下英文嘛,但还是先快速解决问题之后再回头重温下细节。

    

    写了个FreeMarkerUtil工具类,不美欢迎指正

    

package com.bank.pingan.util;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
/**
 * 类作用:
 * 
 * @author xushigang 使用说明:
 */
public class FreeMarkerUtil {
private FreeMarkerUtil() {}
private static final Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
static {
// Create your Configuration instance, and specify if up to what
// FreeMarker
// version (here 2.3.22) do you want to apply the fixes that are not
// 100%
// backward-compatible. See the Configuration JavaDoc for details.
// 创建 freeMarker 配置 ,2.3.24 引入的freemarker 版本号
// Specify the source where the template files come from. Here I set a
// plain directory for it, but non-file-system sources are possible too:
// cfg.setDirectoryForTemplateLoading(new
// File("/where/you/store/templates"));
// cfg.setDirectoryForTemplateLoading(new
// File(PathUtil.getClassResources()+"/ftl/"+ftlPath));
// Set the preferred charset template files are stored in. UTF-8 is
// a good choice in most applications:
// cfg.setEncoding(Locale.CHINA, "utf-8");
cfg.setDefaultEncoding("UTF-8");
// Sets how errors will appear.
// During web page *development*
// TemplateExceptionHandler.HTML_DEBUG_HANDLER is better.
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
}
/**
 * 打印到控制台(测试用)
 * 
 * @param ftlName
 */
public static void print(String ftlName, Map<String, Object> root, String ftlPath) throws Exception {
try {
Template temp = getTemplate(ftlName, ftlPath); // 通过Template可以将模板文件输出到相应的流
temp.process(root, new PrintWriter(System.out));
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
 * 输出到输出到文件
 * 
 * @param ftlName
 *            ftl文件名
 * @param root
 *            传入的map
 * @param outFile
 *            输出后的文件全部路径
 * @param filePath
 *            输出前的文件上部路径
 */
public static void printFile(String ftlName, Map<String, Object> root, String outFile, String filePath, String ftlPath)
        throws Exception {
try {
File file = new File(PathUtil.getClasspath() + filePath + outFile);
if (!file.getParentFile().exists()) { // 判断有没有父路径,就是判断文件整个路径是否存在
file.getParentFile().mkdirs(); // 不存在就全部创建
}
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
Template template = getTemplate(ftlName, ftlPath);
template.process(root, out); // 模版输出
out.flush();
out.close();
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
 * 通过文件名加载模版
 * 
 * @param ftlName
 * @param ftlPath
 *            /ftl/
 * @return
 * @throws Exception
 */
public static Template getTemplate(String ftlName, String ftlPath) throws Exception {
try {
cfg.setDirectoryForTemplateLoading(new File(ftlPath)); // 设定去哪里读取相应的ftl模板文件
Template temp = cfg.getTemplate(ftlName); // 在模板文件目录中找到名称为name的文件
return temp;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
 * 通过文件名加载模版
 * 
 * @param ftlName
 */
public static Template getTemplate(String ftlName) throws Exception {
try {
// cfg.setEncoding(Locale.CHINA, "utf-8");
cfg.setDirectoryForTemplateLoading(new File(PathUtil.getClassResources() + "/config/ftl/")); // 设定去哪里读取相应的ftl模板文件
Template temp = cfg.getTemplate(ftlName); // 在模板文件目录中找到名称为name的文件
return temp;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
 * 将解析之后的文件内容返回字符串
 * 
 * @param name
 *            模板文件名
 * @param root
 *            数据Map
 * @return
 * @throws Exception
 */
public static String printString(String name, Map<String, Object> data) throws Exception {
StringWriter out = new StringWriter();
try {
// 通过一个文件输出流,就可以写到相应的文件中
Template temp = getTemplate(name);
temp.process(data, out);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return out.toString();
}
}

    工具类有了,还要考虑下线程安全问题,比较常见的设计模式如单利模式,下面就看下单利模式线程安全问题。

    单例线程安全

    

    部分报错分析:

    The following has evaluated to null or missing: freemarker

    这个错误是因为值有null 空值了,解决方案是

<td class='center' style="width: 30px;">${val.sqlText!''}</td>

    比如做邮件模板时一般有三种模式:

    1、普通文本

    2、富文本,对用户可见,用百度echarts就可以。如果实现动态表格有点麻烦

    3、模板引擎,构造好数据html发送内容邮件即可。但是对用户较难可见。

©声明:本站原创文章采用 BY-NC-SA 共享协议,受法律保护,转载请注明出处;转载文章版权归原作者所有。
©转载请注明来源:

未经允许不得转载:最优质网--最有指望 » FreeMarker 复习总结

赞 (0) 打赏

评论 0

评论前必须登录!

登陆 注册

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏