1. 程式人生 > >【FreeMarker】【程式開發】異常/錯誤控制

【FreeMarker】【程式開發】異常/錯誤控制

可能的異常

關於FreeMarker發生的異常,可以分為如下幾類:

  • 當載入和解析模板時發生異常:呼叫Configuration.getTemplate()方法,FreeMarker就要把模板檔案載入到記憶體中然後來解析它。在這期間,有兩種異常可能發生:
    • 因模板檔案沒有找到而發生的IOExceptio一場,或在讀取檔案時發生其他I/O問題。比如沒有讀取許可權,或者磁碟錯誤。
    • 根據FTL語言的規則,模板檔案發生語法錯誤時會導致freemarker.core.ParseException一場。當獲得Template物件(Configuration.getTemplate)時,這種錯誤就會發生,而不是執行(Template.process)模板的時候。這種異常是IOException異常的一個子類。
  • 當執行模板時發生的異常,也就是當呼叫了Template.process()方法時會發生的兩種異常:
    • 當試圖寫入輸出物件時發生錯誤而導致的IOException異常
    • 當執行模板時發生的其他問題而導致的freemarker.template.TemplateException異常。比如,當模板引用一個不存在的變數。在預設情況下,當TempalteException異常發生時,FreeMarker會用普通文字格式在輸出中打印出FTL的錯誤資訊和堆疊跟蹤資訊。然後再次丟擲TemplateException異常而中止模板的執行,然後就可以捕捉到Tempalte.process()方法丟擲的異常了。這種行為是可以定製的。

異常處理器 TemplateExceptionHandler

TemplateException 異常在模板處理期間的丟擲是由 freemarker.template.TemplateExceptionHandler 物件控制的,這個物件可以使用 setTemplateExceptionHandler() 方法配置到 Configuration 物件中。

TemplateExceptionHandler物件只包含一個方法:

void handleTemplateException(TemplateException te, Environment env, Writer out) throws TemplateException;

無論 TemplateException 異常什麼時候發生,這個方法都會被呼叫。

如果方法丟擲異常,那麼模板的執行就會中止,而且Template.process() 方法也會丟擲同樣的異常。如果 handleTemplateException 物件不丟擲異常,那麼模板將會繼續執行,就好像什麼也沒發生過一樣,但是引發異常的語句將會被跳過。

當TempalteExceptionHandler被呼叫前,FreeMarker將會記錄異常日誌。

例如:

class MyTemplateExceptionHandler implements TemplateExceptionHandler {
    public void handleTemplateException(TemplateException te, Environment env, java.io.Writer out)
    throws TemplateException {
        try {
            out.write("[ERROR: " + te.getMessage() + "]");
        } catch (IOException e) {
            throw new TemplateException("Failed to print error message. Cause: " + e, env);
        }
    }
}
...
cfg.setTemplateExceptionHandler(new MyTemplateExceptionHandler());

FreeMarker本身帶有的預先編寫的錯誤控制器

  • TemplateExceptionHandler.DEBUG_HANDLER —— 列印堆疊資訊和重新丟擲異常。這是預設的異常控制器
  • TemplateExceptionHandler.HTML_DEBUG_HANDLER —— 和DEBUG_HANDLER相同,但是可以格式化堆疊跟蹤資訊,HTML頁面,建議使用它而不是DEBUG_HANDLER
  • TemplateExceptionHandler.IGNORE_HANDLER —— 簡單地壓制所有異常。它對處理異常沒有任何作用,也不會重新丟擲異常
  • TemplateExceptionHandler.RETHROW_HANDLER —— 簡單重新丟擲所有異常而不會做其他的事情。這個控制器對Web應用很好,因為它在生成的頁面發生錯誤的情況下,給了對Web應用的更多的控制權