我们可以在freemarker模板中使用.get()吗



我正在将速度模板转换为Freemarker,并在下遇到了这种情况

=== Velocity Code ===
#if($frm_BenefitIcons.get("$beni.benefitIconNo"))
#set($xxx = $frm_BenefitIcons.get("$beni.benefitIconNo").toString().substring(12).toUpperCase())
#else
#set($xxx = "")
#end

我把它转换成了

=== Freemarker Code ===
<#if (frm_BenefitIcons.get("${(beni.benefitIconNo)!}"))??>
<#assign xxx = frm_BenefitIcons.get("${(beni.benefitIconNo)!}")?string?substring(12)?upper_case>
<#else>
<#assign xxx = "">
</#if>

这是正确的转换吗?除了使用子字符串之外。我只得到xxx="xxx"的输出"(它是条件的一部分(,而不是实际值(如果是条件的部分(。速度代码给出xxx的输出值。

简而言之(假设您的Configuration使用默认的ObjectWrapper或类似值(,如果get的参数是String,则应该编写frm_BenefitIcons[key]。如果frm_BenefitIconsjava.util.Map,那么您甚至不能调用get。除非,您明确表示要调用对象的Java API:frm_BenefitIcons?api.get(key)。最后一个也是使用非String键查找的方法(因为[]运算符不支持这种方法(。

到转换时,我认为这将是更干净的:

<#assign benefitIcon = frm_BenefitIcons[beni.benefitIconNo?c]!>
<#assign xxx = (benefitIcon != '')?then(benefitIcon[12..]?upper_case, "")>

其中一个关键部分是,在将数字(本例中为beni.benefitIconNo(转换为字符串时,必须使用?c,而不是?string"${n}"。转换为不带?c的字符串需要进行本地化格式化,就像1234可能被格式化为字符串"1,234"一样,这将中断查找。?c格式适用于计算机观众,而不是人类观众,因此避免了任何文化复杂性。

最新更新