前段时间项目需要用到模板技术,本想使用FreeMarker发现有些过时的样子,就搜到了个Beetl,简单一用…
项目背景:
微门户页面上,介绍商家首页信息,而且这些信息比较少又不经常改变。【前期只单单针对商家首页进行静态处理,再由项目二期需要,再优化产品,优惠,等等模块,独立出专门模板服务类】故改用静态文件方式展示,真有需要时可以组建静态资源服务器,与业务服务器分离, 减少服务器压力。
管理端【 发布/更新 】商家信息时调用生成静态文件代码。商家实体添加一属性,作为保存静态文件的相对地址,当页面访问商家首页,直接跳转到该相对地址。
模板文件为【 *.html 】
生成后的静态文件为【 *.html 】
文件存放位置如图所示…
Maven引用
org.beetl
beetl-core
${org.beetl-core.version}
Controller代码如下
String srcTemplateFileName = "companyTemplate.html";
String srcToFileName = "index.html";
Map info = companyService.getStaticInfo(publicAccountId, srcTemplateFileName, srcToFileName);
//生成静态文件对象
companyService.updateTemplateCompany(companyId, info);
//更新该实体对象的静态文件路径
//静态文件路径
String dbToPath = info.get("dbToPath");
//静态文件名称
String toFileName = info.get("toFileName");
//生成后的静态文件相对路径,持久化到实体中
entity.setStaticFilePath(dbToPath + toFileName);
companyService.update(entity);
Service代码如下
@Override
public Map getStaticInfo(Long publicAccountId, String templateFileName, String toFileName) {
Map map = new HashMap();
map.put("templateFileName", "company/" + templateFileName);
map.put("dbToPath", "/resources/static/company/" + dESServiceImpl.encrypt(publicAccountId+"") + "/");
map.put("toPath", WebUtil.getRequest().getSession().getServletContext().getRealPath("/") + "/resources/static/company/" + dESServiceImpl.encrypt(publicAccountId + "") + "/");
map.put("toFileName", toFileName);
//检验生成静态文件目录不存在时自动创建目录
File file = new File(map.get("toPath"));
if(!file.exists()){
file.mkdirs();
}
logger.info("生成静态文件时的路径参数:" + map);
return map;
}
@Override
public void updateTemplateCompany(Long companyId, Map map) {
Company company = super.find(companyId);
Map param = new HashMap();
param.put("company", company);
param.put("basePath", RESOURCESURL);
param.put("path", WebUtil.getRequest().getContextPath());
logger.info("生成模板的参数:" + param);
//模板文件名
String templateFileName = map.get("templateFileName");
//静态路径
String toPath = map.get("toPath");
//静态文件名
String toFileName = map.get("toFileName");
TemplateUtil.templateToFile(templateFileName, toPath, toFileName, param);
}
Beetl代码很简单的封装如下
private static final String DEFAULT_CODE = "UTF-8";
/**
* 模板对象
*/
private static GroupTemplate gt;
/**
* 获取webapp的系统路径
*/
private static final String PATH = WebUtil.getRequest().getSession().getServletContext().getRealPath("/");
/**
* 存放模板的路径(配置到config.properties)
*/
private static final String TEMPLATEFILEPATH = ConfigUtils.config.getProperty("defaultTemplatePath");
static {
FileResourceLoader fileResourceLoader = new FileResourceLoader(PATH + TEMPLATEFILEPATH, DEFAULT_CODE);
logger.info("系统盘模板文件夹:" + PATH + TEMPLATEFILEPATH);
Configuration cfg = null;
try {
cfg = Configuration.defaultConfiguration();
cfg.setCharset(DEFAULT_CODE);
gt = new GroupTemplate(fileResourceLoader, cfg);
} catch (IOException e) {
e.printStackTrace();
logger.error("模板引擎初始化失败", e);
}
}
/**
* 根据模板文件生成静态文件(html)
*
* @param templateFilePath
* 存放模板文件路径
* @param templateFileName
* 模板文件
* @param toPath
* 生成静态文件后存放的路径
* @param toFileName
* 生成静态文件后的文件名称
* @param param
* 对象参数[实体对象,系统路径等]
*/
public static void templateToFile(String templateFileName, String toPath,
String toFileName, Map param) {
// 测试生成时间
Long startTime = System.currentTimeMillis();
// 读取模板文件
Template template = gt.getTemplate(templateFileName);
logger.info("模板文件存放路径:" + (PATH + TEMPLATEFILEPATH + templateFileName));
// 模板数据绑定
template.binding(param);
logger.info("静态文件存放路径:" + (toPath + toFileName));
try {
template.renderTo(new OutputStreamWriter(new FileOutputStream(new File(toPath + toFileName)),DEFAULT_CODE));
} catch (BeetlException e) {
logger.error("输出静态文件出错...");
e.printStackTrace();
} catch (FileNotFoundException e) {
logger.error("输出静态文件出错...");
e.printStackTrace();
}catch (Exception ex){
}
logger.info("耗时:" + (System.currentTimeMillis() - startTime) + "'ms");
}
模板文件代码略,超级简单。因为用到【template.binding(param)】,把Map传入到页面,所以页面就可以如EL表达式取数据【${company.name}】