在 Freemarker 中检测和使用可为空值的问题

Problem detecting and using a nullable value in Freemarker

我有一个从 JSON(在 Java 中)序列化的 POJO 对象。我正在使用通过以下方式构造的对象包装器:

      DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_27);
      builder.setExposeFields(true);
      objectWrapper = builder.build();

我使用 setExposeFields(true) 因为我包装的对象不是 Java bean,而只是一个包含 public 字段的 POJO。

我正在我的模板中执行以下操作:

<@ConditionOccurrence co = c/>

<#macro ConditionOccurrence co>
<#list co?keys as key>
  ${key}
</#list>
${co.occurrenceStartDate!'wtf'}
${co["occurrenceStartDate"]}
A condition occurrence of: ${codesetName(co.codesetId, "any condition")}
<#if co.first!false>- for the first time in the person's history</#if>
<#if (co["occurrenceStartDate"])??>co.OSD is null: </#if>
</#macro>

请注意,'c' 是序列中的一个元素,对我遇到的确切问题并不重要。

模板的输出显示如下:

  stopReason
  getClass
  gender
  CorrelatedCriteria
  providerSpecialty
  occurrenceStartDate
  occurrenceEndDate
  visitType
  accept
  codesetId
  hashCode
  conditionSourceConcept
  equals
  conditionType
  toString
  conditionTypeExclude
  class
  first
  age
org.ohdsi.circe.cohortdefinition.DateRange@68e62ca4
org.ohdsi.circe.cohortdefinition.DateRange@68e62ca4
A condition occurrence of: Psoriasis
- for the first time in the person's history
co.OSD is null: 

第一组行是我的POJO中的所有键。这是对的。 两行输出:

org.ohdsi.circe.cohortdefinition.DateRange@68e62ca4
org.ohdsi.circe.cohortdefinition.DateRange@68e62ca4

这表明字段 occurrenceStartDate 是类型 DateRange 的对象。请注意,这在某些情况下可能为空,因此我正在检查如何检查空...

下一部分输出:

- for the first time in the person's history
co.OSD is null: 

这表明它正在正确读取对象的 'first' 属性,并且我已将原始 JSON 从 'true' 切换为 'false' 和模板正确响应此值的变化。请注意,在对象中,'first' 字段的类型为 Boolean.

第二行:co.OSD is null让我感到困惑。我之前确认输出 'occurrenceStartDate' 字段显示它持有一个 DateRange 对象。但是,此语句的计算结果为 TRUE(即:它为空):

#if (co["occurrenceStartDate"])??>co.OSD is null: </#if>

我试过点号和括号号。出于某种原因,该字段上的 ?? 运算符表示它为空。请注意,底层对象不是简单的 String 或 Number 类型,它是一个简单的 POJO class DateRange,上面有 3 个 String 属性。同样,这些不是 JavaBean,它们只是 POJO。

谁能解释为什么 ?? 运算符明明在引用一个对象时却说它是空的?顺便说一句:如果我尝试访问 co.occurrenceStartDate,它会导致模板错误,我引用了一个空值,所以这里的核心问题是为什么包装器认为它是一个空值?

预先感谢您的帮助。

?? 运算符表示“存在”,而不是“缺失”。所以你的行应该是:

<#if !(co.occurrenceStartDate??)>co.OSD is null: </#if>