在 Freemarker 模板中迭代 HashMap 显示地图的方法
Iterating over HashMap in Freemarker template displays map's methods
在 Apache OfBiz 应用程序中,我在控制器中有这样的代码:
public static String runRequest(HttpServletRequest request, HttpServletResponse response) {
Map<String, Long> typesToCount = getTypesToCount();
request.setAttribute("types", typesToCount);
return HttpFinals.RETURN_SUCCESS;
}
在 freemarker 模板中它是 processed/iterated 像这样:
<table
<#list requestAttributes.types as key, value>
<tr>
<td>${key}</td>
<td>${value}</td>
</tr>
</#list>
</table>
在呈现的 html 页面上,我得到了实际地图的字符串键和地图的方法名称(放置、删除、添加等)。
至于值,它们根本没有呈现,并出现以下错误:
FreeMarker template error: For "${...}" content: Expected a string or something automatically convertible to string (number, date or boolean), or "template output" , but this has evaluated to a method+sequence (wrapper: f.e.b.SimpleMethodModel)
我正在使用 freemarker 2.3.28
如果 FreeMarker 配置为使用纯 BeansWrapper
(而不是 DefaultObjectWrapper
)作为其 object_wrapper
设置,并且 BeansWrapper.simpleMapWrapper
属性 保留其默认值 false
。不用说,这是一个非常有问题的配置。希望它不是 OfBiz 的默认值。尽管对于旧框架来说,这可能会发生,但在许多年前,这是一种解决 FreeMarker 某些限制的方法,因为这样您就可以只使用 Map
的 Java API。后来,?api
内置函数的引入使这个 hack 变得不必要了。
Map.entrySet() 方法 returns 此映射中包含的映射的集合 (Set<Map.Entry<K, V>>
)。所以我们可以使用 Map.Entry<K, V>
的 getKey() 和 getValue() 方法迭代键值对。此方法最常见,如果您在循环中同时需要映射键和值,则应使用此方法。
尝试使用此代码循环访问 FTL 中的值
<table>
<#list requestAttributes.entrySet() as requestAttribute>
<tr>
<td>${requestAttribute.getKey()}</td>
<td>${requestAttribute.getValue()}</td>
</tr>
</#list>
</table>
基本上,只有在将地图包装在 SimpleMapModel 中后,我才设法遍历地图,如下所示:
public static String runRequest(HttpServletRequest request, HttpServletResponse response) {
Map<String, Long> typesToCount = getTypesToCount();
request.setAttribute("types", new SimpleMapModel(typesToCount, new DefaultObjectWrapper())));
return HttpFinals.RETURN_SUCCESS;
}
和 int ftl 模板:
<#list requestAttributes.types?keys as key>
<tr>
<td>${key}</td>
<td>${requestAttributes.types[key]}</td>
</tr>
</#list>
在 Apache OfBiz 应用程序中,我在控制器中有这样的代码:
public static String runRequest(HttpServletRequest request, HttpServletResponse response) {
Map<String, Long> typesToCount = getTypesToCount();
request.setAttribute("types", typesToCount);
return HttpFinals.RETURN_SUCCESS;
}
在 freemarker 模板中它是 processed/iterated 像这样:
<table
<#list requestAttributes.types as key, value>
<tr>
<td>${key}</td>
<td>${value}</td>
</tr>
</#list>
</table>
在呈现的 html 页面上,我得到了实际地图的字符串键和地图的方法名称(放置、删除、添加等)。
至于值,它们根本没有呈现,并出现以下错误:
FreeMarker template error: For "${...}" content: Expected a string or something automatically convertible to string (number, date or boolean), or "template output" , but this has evaluated to a method+sequence (wrapper: f.e.b.SimpleMethodModel)
我正在使用 freemarker 2.3.28
如果 FreeMarker 配置为使用纯 BeansWrapper
(而不是 DefaultObjectWrapper
)作为其 object_wrapper
设置,并且 BeansWrapper.simpleMapWrapper
属性 保留其默认值 false
。不用说,这是一个非常有问题的配置。希望它不是 OfBiz 的默认值。尽管对于旧框架来说,这可能会发生,但在许多年前,这是一种解决 FreeMarker 某些限制的方法,因为这样您就可以只使用 Map
的 Java API。后来,?api
内置函数的引入使这个 hack 变得不必要了。
Map.entrySet() 方法 returns 此映射中包含的映射的集合 (Set<Map.Entry<K, V>>
)。所以我们可以使用 Map.Entry<K, V>
的 getKey() 和 getValue() 方法迭代键值对。此方法最常见,如果您在循环中同时需要映射键和值,则应使用此方法。
尝试使用此代码循环访问 FTL 中的值
<table>
<#list requestAttributes.entrySet() as requestAttribute>
<tr>
<td>${requestAttribute.getKey()}</td>
<td>${requestAttribute.getValue()}</td>
</tr>
</#list>
</table>
基本上,只有在将地图包装在 SimpleMapModel 中后,我才设法遍历地图,如下所示:
public static String runRequest(HttpServletRequest request, HttpServletResponse response) {
Map<String, Long> typesToCount = getTypesToCount();
request.setAttribute("types", new SimpleMapModel(typesToCount, new DefaultObjectWrapper())));
return HttpFinals.RETURN_SUCCESS;
}
和 int ftl 模板:
<#list requestAttributes.types?keys as key>
<tr>
<td>${key}</td>
<td>${requestAttributes.types[key]}</td>
</tr>
</#list>