在Freemarker模板中遍历HashMap会显示地图的方法

时间:2018-11-14 12:14:14

标签: freemarker ofbiz

在Apache OfBiz应用程序中,我在控制器中有这样的代码:

   public static String runRequest(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Long> typesToCount = getTypesToCount();
        request.setAttribute("types", typesToCount);
        return HttpFinals.RETURN_SUCCESS;
   }

在freemarker模板中,其处理/迭代方式如下:

<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

3 个答案:

答案 0 :(得分:3)

Map.entrySet()方法返回此映射中包含的映射的集合(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>

答案 1 :(得分:1)

如果FreeMarker的BeansWrapper设置使用纯DefaultObjectWrapper(而不是object_wrapper),并且BeansWrapper.simpleMapWrapper属性保留在其默认值false。不用说,这是一个非常有问题的配置。希望它不是OfBiz的默认设置。尽管对于旧框架来说,这种情况可能发生,但许多年前,这是一种解决FreeMarker局限性的方法,因为这种方式只能使用Map的Java API。后来,内置?api的引入使此黑客不再需要。

答案 2 :(得分:1)

基本上,只有在将地图包装到 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>