<#if myVar = "test">
A
<#else>
B
<#/if>
如果myVar
为空/未定义,则A和B都不会输出。这是通过在变量后添加!
来修复的
<#if myVar! = "test">
A
<#else>
B
<#/if>
这是有意的吗?因为如果是这样的话,它会非常令人困惑,我无法想象任何用户会期望它这样做。这表明null = "test"
在某种程度上既不是真的也不是假的。很明显,null = "test"
应该总是被认为是假的——我缺少了什么?
注意:我们已经配置了Freemarker,将未知变量替换为空字符串:
config.setTemplateExceptionHandler((ex, environment, out) ->
{
if (ex instanceof InvalidReferenceException)
{
try
{
out.write("");
}
catch (IOException e)
{
throw new TemplateException("Error while handling template exception.", e, environment);
}
}
else
{
throw ex;
}
});
所以这将(至少我认为它会(最终成为:
<#if "" = "test">
A
<#else>
B
<#/if>
在这种情况下,我肯定会输入else
,但事实并非如此。
举个例子:
<#assign myVar = null/>
<#if myVar == "test">
A
<#else>
B
</#if>
这会引发以下错误:
以下内容已评估为null或缺失:===>空
myVar
被评估为null或缺失——这似乎是我感到困惑的原因;Freemarker不会区分缺失值和现有值,但我想是空值吗?
无论是#if
/#else
还是任何其他指令调用都无关紧要,因为当发生错误(任何类型的TemplateException
,而不仅仅是"缺失值"(时,整个语句都会被跳过。不是可变分辨率,甚至不是整个表达式,而是整个语句。这也是手册和Javadoc所说的,比如:https://freemarker.apache.org/docs/pgui_config_errorhandling.html.因此,templateExceptionHandler
设置不用于为缺失值提供默认值。这是为了处理真正错误的情况。比如,有人犯了一个错误,有些事情无法操作。
至于为什么不坐#else
呢。当在评估条件时发生错误时,模板引擎无法判断如果开发人员(或任何人(没有犯错误,会采取哪个分支。选择if
/else
的任何一个分支都是一场赌博。(这甚至不是一场五五开的赌博,因为考虑到输出的真实世界意义,正分支往往是正确的,然而,如果有什么不同的话,人们希望模板引擎将赌注押在else
分支上。(因此,希望你至少能打印一些错误指标,它不会选择任何一个分支。但它确实是自动的,因为整个#if
/#elseif
/#else
都是一个大声明。
<#assign myVar = "test"/>
<#if myVar?? && myVar == "test">
A
<#else>
B
</#if>
是的。当变量未定义或为null时,freemarker将引发错误。
常见问题解答中对此进行了解释:为什么FreeMarker对null-s和缺少的变量如此挑剔,以及如何处理它?
这是该框架最初作者的设计选择。如果您不能满足此选择,则可以使用默认值运算符(使用myVar!
而不是myVar
(,或者使用其他模板框架。
您添加的自定义异常处理程序不会用空字符串替换表达式,而是替换完整的if/else表达式。