概要
<#attempt>
attempt block
<#recover>
recover block
</#attempt>
这里:
-
attempt block:任意内容的模板块。这是会被执行的, 但是如果期间发生了错误,那么这块内容的输出将会回滚, 之后recover block就会被执行。 -
recover block: 任意内容的模板块。 这个仅在attempt block执行期间发生错误时被执行。你可以在这里打印错误信息或其他操作。
recover 是强制的。
attempt/recover 可以嵌套在其他
attempt block 或
recover block中。
上面的格式是从 2.3.3 版本开始支持的,之前它是
<#attempt>...<#recover>...</#recover>,也支持向下兼容。此外,
这些指令是在 FreeMarker 2.3.1 版本时引入的,在 2.3 版本中是不存在的。
描述
如果你想让页面成功输出内容,尽管它在页面特定位置发生错误也这样,
那么这些指令就是有用的。如果一个错误在
attempt block 执行期间发生,
那么模板执行就会中止,但是 recover block
会代替 attempt block 执行。
如果在 attempt block 执行期间没有发生错误,
那么 recover block 就会忽略。
一个简单的示例如下:
Primary content
<#attempt>
Optional content: ${thisMayFails}
<#recover>
Ops! The optional content is not available.
</#attempt>
Primary content continued如果 thisMayFails 变量不存在,将会输出:
Primary content Ops! The optional content is not available. Primary content continued
如果 thisMayFails 变量存在而且值为
123,将会输出:
Primary content Optional content: 123 Primary content continued
attempt block
块有多或没有的语义:不管 attempt
block块的完整内容是否输出(没有发生错误),
或者在 attempt block
(没有发生错误)块执行时没有输出结果。比如,上面的示例,
发生在"Optional content"之后的失败被打印出来了,而没有在"Ops!"之前输出。
(这是在
attempt block
块内,侵入的输出缓冲的实现,甚至连 flush
指令也会送输出到客户端。)
为了阻止来自上面示例的误解:
attempt/recover
不(仅仅)是处理未定义变量(可以使用 不存在变量控制符)。
它可以处理发生在块执行期间的各种类型的错误
(而不是语法错误,这会在执行之前被检测到)。它的目的是包围更大的模板段,
错误可能发生在很多地方。比如,你在模板中有一个部分,来处理打印广告,
但是它不是页面的主要内容,所以你不想你的页面因为一些打印广告
(也可能是短暂的数据库服务器故障)的错误而挂掉。
所以你将整个广告区域放在 attempt
block 块中。
在一些环境下,程序员配置 FreeMarker,所以对于特定的错误,
它不会中止模板的执行,在打印一些错误提示信息到输出
(更多内容,请参考 这里...)中之后,
而是继续执行。attempt 指令不会将这些抑制的错误视为错误。
在 recover block
块中,错误的信息存在 特殊变量 error 中。
不要忘了以点开始引用特殊变量(比如:${.error})。
在模板执行期间发生的错误通常被 日志记录,不管是否发生在
attempt
block块中。