Итерирование по HashMap в шаблоне Freemarker отображает методы карты - PullRequest
0 голосов
/ 14 ноября 2018

В приложении 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 голосов
/ 16 ноября 2018

Метод Map.entrySet () возвращает коллекцию (Set<Map.Entry<K, V>>) сопоставлений, содержащихся в этой карте.Таким образом, мы можем перебрать пару ключ-значение с помощью методов getKey () и getValue () Map.Entry <K, V>.Этот метод является наиболее распространенным и должен использоваться, если вам нужны и ключи карты, и значения в цикле.

Попробуйте этот код для перебора значений в FTL

<table>
  <#list requestAttributes.entrySet() as requestAttribute>
  <tr>
    <td>${requestAttribute.getKey()}</td>
    <td>${requestAttribute.getValue()}</td>
  </tr>
  </#list>
</table>
0 голосов
/ 20 ноября 2018

По сути, мне удалось перебрать карту только после ее оборачивания в 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>
0 голосов
/ 14 ноября 2018

Это работает так, если FreeMarker сконфигурирован для использования чистого BeansWrapper (в отличие от DefaultObjectWrapper) для его настройки object_wrapper, а свойство BeansWrapper.simpleMapWrapper остается в его значении по умолчанию false. Излишне говорить, что это довольно проблематичная конфигурация для работы. Надеюсь, это не по умолчанию OfBiz. Хотя для старых фреймворков это может произойти, так как много лет назад это был способ обойти некоторые ограничения FreeMarker, так как таким образом вы можете просто использовать Java API Map. Позже, введение встроенного ?api сделало этот хак ненужным.

...