自从更改 SpringBoot 依赖性以来,在空字段上加入时出现 Freemarker 错误

Freemarker error when ?join on null field since changing SpringBoot dependency

已解决:错误已经存在,我只是假设我最近创建了它...


我有一个使用 SpringMVC 和 Freemarker 的项目。
在我的控制器中,我向名为 activities 的模型添加了一个属性,如下所示:

@GetMapping("/activities/{floorId}")
public String activities(Model model, @PathVariable String floorId) {
    model.addAttribute("activities", activityService.getActivitiesForFloor(floorId));
    return "floor/activities";
}

activities 有一个名为 involvedTiles 的字段,有时是 null。这很好。
在我的 Freemarker 视图中,我使用这样的模型属性:

<#list activities as activity>
<tr>
    <td>${activity.id}</td>
    <td>${activity.involvedTiles?join(", ")}</td>
</tr>
</#list>

这一直有效(从未出错)。但是现在我突然得到这个错误:

2016-10-21 13:56:17,163 ERROR [http-nio-8080-exec-10] o.a.c.c.C.[.[.[.[dispatcherServlet] [DirectJDKLog.java:181] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is freemarker.core.InvalidReferenceException: The following has evaluated to null or missing:
==> activity.involvedTiles  [in template "floor/activities.ftl" at line 51, column 27]

----
Tip: It's the step after the last dot that caused this error, not those before it.
----
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#deleted-channelwhen-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
...etc...

我知道我遇到了这个错误,因为 activity.involvedTilesnull 并且我尝试将它与 ?join() 函数一起使用。但我不明白为什么这突然停止工作。我唯一能想到的是我已经将我的 SpringBoot 依赖项从 1.3.0.RELEASE 更新到 1.4.1.RELEASE。在 SpringBoot 1.3.0 他们使用 org.freemarker 2.3.23 and in SpringBoot 1.4.1 they use org.freemarker 2.3.25-incubating.
我的问题:Freemarker 是否更改了某些内容,这就是我收到此错误的原因吗?


我检查了 site of freemarker 2.3.23 and freemarker 2.3.25 但找不到解释此错误的内容。

首先,您可以在控制器级别循环此活动集合,然后再将其放入模型映射中。在循环中,您可以检查 activity 的值和 activity.involvedTiles 的值。如果控制器端的值正在打印,您可以确认错误在哪里。如果那里的值为 null 那么你不需要找到关于 freemarker 的信息。

如何处理 freemarker 中的空值
在 freemarker 中,您可以像这样处理空值。

    <td><#if activity.involvedTiles??>${activity.involvedTiles?join(", ")}</#if></td>   

完整的 ftl 文件

<#list activities as activity>
<tr>
    <td>${activity.id}</td>
    <td><#if activity.involvedTiles??>${activity.involvedTiles?join(", ")}</#if></td>   
</tr>
</#list>

?join 从未打算容忍 null,据我所知也没有这样的错误(意外地允许 null)。另外,我已经用 FreeMarker 2.3.21(一个非常旧的版本)试过了,它仍然不允许 null 在那里。