FreeMarker Error : left-hand operand: Expected a hash, but this evaluated to a sequence

本文解决了一个关于FreeMarker模板语言中获取列表大小的问题。当尝试将列表的大小赋值给变量时出现了错误,通过调整语法成功解决了该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

When I loop through a list in freemarker like below, it works fine.

<#list cModel.products as product>

But when I'm tring to assign the size of the list to a variable like,

 <#assign totalProducts = cModel.products.getList()?size>

I'm getting an exception from free marker like below

left-hand operand: Expected a hash, but this evaluated to a sequence

Any suggestions?

share improve this question
 
 
What is the signature of Product.getList()? Post the Java. –  Raedwald  Jul 27 '14 at 7:43

1 Answer

up vote 5 down vote accepted

I Hope you've accessing it wrongly.

As per your example, the list name is product. So,

<#assign totalProducts = cModel.getProducts()?size>

Should return back the size of the products.

Hope it helps.

share improve this answer
 
 
Thanks for your reply. It resolved the issue. –  javaAnto  Jul 27 '14 at 13:25
1 
cModel.products?size is the nicer way of doing that. –  ddekany  Jul 27 '14 at 13:57 
<think>嗯,用户问的是FreeMarker报错“Expected a number but this has evaluated to a string”。首先,我需要确定这个错误的常见原因。FreeMarker在尝试进行数值运算时,如果变量是字符串类型,就会抛出这个错误。例如,用户可能在模板中写了类似${num + 1}的表达式,而num实际上是一个字符串。 接下来,我应该考虑用户可能的场景。他们可能在处理数据时,从数据库或其他数据源获取了数值,但数据实际存储为字符串,比如JSON或数据库中的VARCHAR字段。或者在表单提交时,字段值以字符串形式传递,没有正确转换为数字。 然后,我需要整理解决步骤。首先检查数据类型,确认变量是否为字符串。可以通过${num?string}或${num?typeof}来查看类型。如果是字符串,就需要转换类型,使用?number方法,比如${num?number + 1}。但要注意,如果字符串无法转换为数字,会报错,所以可能需要先验证。 另外,数据源的预处理也很重要。建议在将数据传递给模板前,确保它们是数值类型。比如在Java中,检查并转换类型。同时,模板中的默认值处理,使用!运算符避免null,但要小心空字符串导致转换失败。 还需要提醒用户注意区域设置问题,比如小数点符号可能因地区不同而不同,导致转换失败。这时候可以用?number?string.computer来处理。 最后,给出示例代码,展示错误和正确写法,帮助用户理解。同时总结关键点,强调类型检查和转换的重要性,以及预处理的最佳实践。</think>好的,我来逐步解释这个FreeMarker错误的含义及解决方法: #### 错误背景 当FreeMarker模板中出现以下报错时: ``` freemarker expected a number but this has evaluated to string ``` 表示**模板引擎尝试执行数值运算,但发现变量实际是字符串类型**。 --- #### 常见场景分析 1. **数据源问题** ```ftl ${price * 0.9} <#-- price实际是"100"而非100 --> ``` - 当`price`是字符串(如`"100"`)而非数字时,乘法运算会失败 2. **表单/参数传递问题** ```ftl <#assign page = requestParameters.page> <#-- URL参数默认是字符串 --> ${page + 1} <#-- 试图对字符串进行加法 --> ``` 3. **JSON/XML数据问题** ```json {"age": "25"} <#-- 数值被错误地定义为字符串 --> ``` ```ftl ${user.age > 18} <#-- 比较运算需要数值类型 --> ``` --- #### 解决步骤 1. **检查变量类型** ```ftl ${num?string} <#-- 输出变量原始值 --> ${num?typeof} <#-- 显示变量类型 --> ``` 2. **强制类型转换** ```ftl <#-- 基本转换 --> ${num?number + 1} <#-- 安全转换(避免无效值报错) --> <#if num?is_number> ${num + 1} <#else> Invalid number </#if> ``` 3. **数据源预处理** ```java // Java示例:在传入模板前转换类型 Map<String, Object> data = new HashMap<>(); String priceStr = "99.9"; data.put("price", Double.parseDouble(priceStr)); // 转为数字类型 ``` 4. **处理空值/默认值** ```ftl <#-- 使用默认值但要确保类型正确 --> ${(num!0)?number} <#-- 处理null值并转换类型 --> ``` --- #### 特殊注意事项 - **区域格式问题** ```ftl <#-- 处理欧洲数字格式 "1.234,56" --> ${"1.234,56"?replace(".","")?replace(",",".")?number} 或 ${"1.234,56"?number?string.computer} ``` - **Boolean陷阱** ```ftl <#-- 字符串"true"不能直接当布尔值使用 --> <#if isActive?string == "true"> <#-- 错误方式 --> <#if isActive?c == "true"> <#-- 正确方式 --> ``` --- #### 示例对比 **错误写法** ```ftl <#assign strNum = "123"> ${strNum * 2} <#-- 报错:字符串无法参与运算 --> ``` **正确写法** ```ftl <#assign strNum = "123"> ${strNum?number * 2} <#-- 输出246 --> 或 <#assign realNum = strNum?number> ${realNum * 2} ``` --- #### 总结要点 1. 使用`?number`进行显式类型转换 2. 在数据传入模板前确保类型正确 3. 使用`?typeof`调试变量类型 4. 注意数字格式的区域差异 5. 对用户输入进行有效性验证 建议在开发过程中添加类型检查逻辑,可以有效预防此类问题: ```ftl <#attempt> ${unknownVar * 2} <#recover> Error: 类型不匹配 </#attempt> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值