可能的异常
关于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应用的更多的控制权