FreeMarker 生成静态html文件及中文乱码的问题


FreeMarker 允许 Java servlet 保持图形设计同应用程序逻辑的分离,这是通过在模板中密封 HTML 完成的。模板 用 servlet 提供的数据动态地生成 HTML。模板语言是强大的直观的,编译器速度快,输出接近静态 HTML 页面的速度。 FreeMarker 是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯 Java 编写 FreeMarker 被设计用来 生成 HTML Web 页面,特别是基于 MVC 模式的应用程序。 虽然 FreeMarker 具有一些编程的能力,但通常由 Java 程序准备要显示的数据,由 FreeMarker 生成页面,通过模 板显示准备的数据。 FreeMarker 不是一个 Web 应用框架,而适合作为 Web 应用框架一个组件。 FreeMarker 与容器无关,因为它并不知道 HTTP 或 Servlet;FreeMarker 同样可以应用于非 Web 应用程序环境 FreeMarker 更适合作为 Model2 框架(如 Struts)的视图组件,你也可以在模板中使用 JSP 标记库 FreeMarker 是免费的 模板: 查看文章: ${newsitem.title}
${newsitem.title} ( ${newsitem.addtime} ) 返回

${newsitem.showContent}
代码: import java.io.*; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import freemarker.template.*; /* * Created on 2005-4-7 * */ /** * 测试 FreeMarker. * * @author scud * */ public class FreeMarkerTest { private final Log logger = LogFactory.getLog(getClass()); private Configuration freemarker_cfg = null; public static void main(String[] args) { //@todo 自己的一个类 NewsItem aItem = null; //@todo 装入新闻 //NewsItem = loadNewsItem(1); FreeMarkerTest test = new FreeMarkerTest(); Map root = new HashMap(); root.put("newsitem", aItem); String sGeneFilePath = "/tpxw/"; String sFileName = "1.htm"; boolean bOK = test.geneHtmlFile("/tpxw/view.ftl",root, sGeneFilePath,sFileName); } /** * 获取 freemarker 的配置. freemarker 本身支持 classpath,目录和从 ServletContext 获取. */ protected Configuration getFreeMarkerCFG() { if (null == freemarker_cfg) { // Initialize the FreeMarker configuration; // - Create a configuration instance freemarker_cfg = new Configuration(); // - FreeMarker 支持多种模板装载方式,可以查看 API 文档,都很简单:路径,根据 Servlet 上下文, classpath 等等 //htmlskin 是放在 classpath 下的一个目录 freemarker_cfg.setClassForTemplateLoading(this.getClass(), "/htmlskin"); } return freemarker_cfg; } /** * 生成静态文件. * * @param templateFileName 模板文件名,相对 htmlskin 路径,例如"/tpxw/view.ftl" * @param propMap 用于处理模板的属性 Object 映射 * @param htmlFilePath 要生成的静态文件的路径,相对设置中的根路径,例如 "/tpxw/1/2005/4/" * @param htmlFileName 要生成的文件名,例如 "1.htm" */ public boolean geneHtmlFile(String templateFileName,Map propMap, String htmlFilePath,String ht mlFileName ) { //@todo 从配置中取得要静态文件存放的根路径:需要改为自己的属性类调用 String sRootDir = "e:/webtest/htmlfile" ; try { Template t = getFreeMarkerCFG().getTemplate(templateFileName); //如果根路径存在,则递归创建子目录 creatDirs(sRootDir,htmlFilePath); File afile = new File(sRootDir +"/" +htmlFilePath + "/" + htmlFileName); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(afile))); t.process(propMap, out); } catch (TemplateException e) { logger.error("Error while processing FreeMarker template " + templateFileName,e); return false; } catch (IOException e) { logger.error("Error while generate Static Html File " + htmlFileName,e); return false; } return true; } /** * 创建多级目录 * * @param aParentDir String * @param aSubDir 以 / 开头 * @return boolean 是否成功 */ public static boolean creatDirs(String aParentDir, String aSubDir) { File aFile = new File(aParentDir); if (aFile.exists()) { File aSubFile = new File(aParentDir + aSubDir); if (!aSubFile.exists()) { return aSubFile.mkdirs(); } else { return true; } } else { return false; } } } 编码的问题 这里说的是编码的问题。项目使用的都是 UTF-8 编码,生成的文件在 UTF-8 编码下察看是乱码,而 GBK 正常(后来 发现因为我用的中文操作系统所以用 GBK 查看正常)。 当然我把 Freemarker 的配置都改成了 UTF-8,我的模版文件也是 UTF-8 编码的。下面是原来的代码 public void setTemplatePath(Resource templatePath) { this.templatePath = templatePath; //设置 freemarker 的参数 freemarkerCfg = new Configuration(); try { freemarkerCfg.setDirectoryForTemplateLoading(this.templatePath.getFile()); freemarkerCfg.setObjectWrapper(new DefaultObjectWrapper()); freemarkerCfg.setDefaultEncoding("UTF-8"); } catch (IOException ex) { throw new SystemException("No Directory found,please check you config."); } } /** * 生成静态文件 * @param templateFileName 模版名称 eg:(biz/order.ftl) * @param propMap 用于处理模板的属性 Object 映射 * @param htmlFilePath 要生成的静态文件的路径,相对设置中的根路径,例如 "/biz/2006/5/" * @param htmlFileName 要生成的文件名,例如 "123.htm" * @return */ private boolean buildHtml(String templateFileName,Map propMap, String htmlFilePath,String htmlFil eName) { try { Template template = freemarkerCfg.getTemplate(templateFileName); template.setEncoding("UTF-8"); //创建生成文件目录 creatDirs(buildPath.getFilename(),htmlFilePath); File htmlFile = new File(buildPath + htmlFilePath + htmlFileName); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile))); template.process(propMap,out); out.flush(); return true; } catch (TemplateException ex) { log.error("Build Error"+templateFileName,ex); return false; } catch (IOException e) { log.error("Build Error"+templateFileName,e); return false; } } 下面是修改之后的代码 /** * 生成静态文件 * @param templateFileName 模版名称 eg:(biz/order.ftl) * @param propMap 用于处理模板的属性 Object 映射 * @param htmlFilePath 要生成的静态文件的路径,相对设置中的根路径,例如 "/biz/2006/5/" * @param htmlFileName 要生成的文件名,例如 "123.htm" * @return */ private boolean buildHtml(String templateFileName,Map propMap, String htmlFilePath,String htmlFile Name) { try { Template template = freemarkerCfg.getTemplate(templateFileName); template.setEncoding("UTF-8"); //创建生成文件目录 creatDirs(buildPath.getFilename(),htmlFilePath); File htmlFile = new File(buildPath + htmlFilePath + htmlFileName); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile),"UTF -8")); template.process(propMap,out); out.flush(); return true; } catch (TemplateException ex) { log.error("Build Error"+templateFileName,ex); return false; } catch (IOException e) { log.error("Build Error"+templateFileName,e); return false; } } 原因就在于 OutputStreamWriter 的不同构造方法 OutputStreamWriter(OutputStream out) 创建使用默认字符编码的 OutputStreamWriter。 OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。 这个是中文 JDK 的文档说明,刚开始我使用默认的构造函数,所以使用了系统默认的编码,GBK,所以在生成静态 文件的时候把 UTF-8 内容用 GBK 编码写入了,所以在 UTF-8 下浏览就有问题。 还有关于修改模版文件同样也要注意这个问题。 public String loadTemplate(String templateName) { StringBuffer sb = new StringBuffer(); try { File file = new File(templatePath+"/"+templateName); BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); String line = reader.readLine(); while(line != null) { sb.append(line); sb.append("\r\n"); line = reader.readLine(); } reader.close(); } catch (IOException e) { throw new SystemException("Loading template Error:",e); } return sb.toString(); } public void saveTemplate(String templateName, String templateContent) { try { File file = new File(templatePath + "/" + templateName); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8 ")); out.write(templateContent); out.flush(); //扔出 templatesave 事件 TemplateSaveEvent evt = new TemplateSaveEvent(); evt.setTemplateName(templateName); dispatchTemplateEvent(evt); } catch (IOException e) { throw new SystemException("Write template Error",e); } }
还剩6页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 -200 金币 [ 分享pdf获得金币 ] 30 人已下载

下载pdf

pdf贡献者

46680060

贡献于2011-11-15

下载需要 -200 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf