关于Freemarker生成静态文件的问题

阅读更多
首先感谢JScud提供的好文章。《 使用FreeMarker生成Html静态文件(实例)》
      在我们的项目中也用到了Freemarker生成静态文件。不过这里我要说的是编码的问题。我们的项目使用的都是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 htmlFileName){
        
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 htmlFileName){
        
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);
        }
    }



莫多 2006-06-21 10:46 发表评论

你可能感兴趣的:(freemarker,JDK)