關於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);
        }
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章