处理不存在的变量

假如我们在模版中引用了一个不存在的变量,FreeMaker将抛出错误信息,如下:

<html>
<head>
    <title>处理不存在的变量</title>
</head>
<body>

<p>
    version=${version}
</p>

</body>
</html>

上面模版中的 version 变量实际上是不存在。错误信息:

六月 25, 2020 10:34:08 下午 freemarker.log._JULLoggerFactory$JULLogger error
严重: Error executing FreeMarker template
FreeMarker template error:
The following has evaluated to null or missing:
==> version  [in template "template11.ftl" at line 8, column 15]

----
Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: ${version}  [in template "template11.ftl" at line 8, column 13]
----

在数据模型中经常会有可选的变量(也就是说有时并不存在)。除了一些典型的人为原因导致失误外,FreeMarker 绝不能容忍引用不存在的变量,除非明确地告诉它当变量不存在时如何处理。一个不存在的变量和一个是 null 值的变量,对于 FreeMarker 来说是一样的,所以这里所指的 "丢失" 包含这两种情况。下面介绍两种处理变量不存在的方法:

方法一:指定默认值

不论在哪里引用变量,都可以指定一个默认值来避免变量丢失这种情况,通过在变量名后面跟着一个 !(叹号) 和 默认值。 例如:

<p>
    version=${version!"v1.0.0"}
</p>

上面当 version 变量不存在时,将输出“v1.0.0”字符串。

也可以使用“?default('默认值')”方式,如下:

<p>
    version=${version?default("v1.0.0")}
</p>

方法二:if 指令判断

我们还可以在变量名后面通过放置 ?? 来询问一个变量是否存在。将 ?? 和 if 指令合并,如下:

<#if version??>
<p>
    version=${version}
</p>
</#if>

关于多级访问的变量,比如 user.url.port,书写代码:user.url.port!80 当且仅当 user.url永远存在,而仅仅最后一个子变量 port 可能不存在时是正确的 (这种情况下我们假设默认端口为 80)。如果 user 或 url 不存在, 那么模板处理过程将会以“未定义的变量”错误而停止。如下:

// 数据模型
Map<String, Object> input = new HashMap<String, Object>();
Map<String, Object> user = new HashMap<String, Object>();
user.put("name", "hxstrive");
user.put("email", "hxstrive@outlook.com");
user.put("url", null); // { host:'www.hxstrive.com', protocol:'http', port:80 }
input.put("user", user);

模型代码:

<html>
<head>
    <title>处理不存在的变量</title>
</head>
<body>

<p>name:${user.name}</p>
<p>email:${user.email}</p>
<p>url:${user.url.protocol}://${user.url.host}:${user.url.port}</p>

</body>
</html>

为了防止这种情况的发生, 可以如下这样来编写代码 (user.url.port)!80。 这种情况就是说 user 或 url 不存在时,表达式的结果是 80。对于 ?? 也是同样用来的处理这种逻辑的; 将 user.url.port?? 改为(user.url.port)??。如下:

<html>
<head>
    <title>处理不存在的变量</title>
</head>
<body>

<p>name:${user.name}</p>
<p>email:${user.email}</p>
<p>url:${(user.url.protocol)!"http"}://${(user.url.host)!"www.hxstrive.com"}:<#if (user.url.port)??>${user.url.port}</#if></p>

</body>
</html>


说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号