Freemarker выполняет итерацию по клавишам hashmap

Freemarker имеет два типа данных коллекции, списки и хэшмапы Есть ли способ перебрать ключи hashmap так же, как мы делаем со списками?

Итак, если у меня есть var с данными, скажем:

user : {
  name : "user"
  email : "[email protected]"
  homepage : "http://nosuchpage.org"
}

Я хотел бы напечатать все свойства пользователя с их значением. Это неверно, но цель понятна:

<#list user.props() as prop>
  ${prop} = ${user.get(prop)}
</#list>

Ответ 1

Изменить: Больше не использовать это решение, особенно не .get(prop). См. Другие ответы.

Вы используете встроенную функцию функции, например. это должно работать:

<#list user?keys as prop>
    ${prop} = ${user.get(prop)}
</#list>  

Ответ 2

FYI, похоже, что синтаксис для извлечения значений изменился в соответствии с:

http://freemarker.sourceforge.net/docs/ref_builtins_hash.html

<#assign h = {"name":"mouse", "price":50}>
<#assign keys = h?keys>
<#list keys as key>${key} = ${h[key]}; </#list>

Ответ 3

Начиная с версии 2.3.25, сделайте следующее:

<#list user as propName, propValue>
  ${propName} = ${propValue}
</#list>

Обратите внимание, что это также работает с нестроковыми клавишами (в отличие от map[key], который должен был быть записан как map?api.get(key))).

До 2.3.25 стандартное решение было:

<#list user?keys as prop>
  ${prop} = ${user[prop]}
</#list>

Однако некоторые действительно старые интеграции FreeMarker используют странную конфигурацию, где в качестве ключей отображаются общедоступные методы Map (например, getClass). Это происходит, когда они используют чистый BeansWrapper (вместо DefaultObjectWrapper), свойство simpleMapWrapper осталось на false. Вам следует избегать такой настройки, поскольку она смешивает методы с реальными элементами Map. Но если вы столкнетесь с такой неудачной настройкой, способ избежать ситуации - использовать открытые Java-методы, такие как user.entrySet(), user.get(key) и т.д., И не использовать конструкторы языка шаблонов, такие как ?keys или user[key].

Ответ 4

Если вы используете BeansWrapper с уровнем экспозиции Expose.SAFE или Expose.ALL, тогда может использоваться стандартный Java-подход к итерации набора записей:

Например, во Фримаркере (начиная с версии 2.3.19) будет работать следующее:

<#list map.entrySet() as entry>  
  <input type="hidden" name="${entry.key}" value="${entry.value}" />
</#list>

В Struts2, например, расширение BeanWrapper используется с уровнем экспозиции по умолчанию, чтобы разрешить этот способ итерации.

Ответ 5

Итерация объектов

Если ваши ключи карты являются объектом, а не строкой, вы можете повторить его с помощью Freemarker.

1) Преобразуйте карту в список в контроллере:

List<Map.Entry<myObjectKey, myObjectValue>> convertedMap  = new ArrayList(originalMap.entrySet());

2) Итерируйте карту в шаблоне Freemarker, обращаясь к объекту в ключе и объекте в значении:

<#list convertedMap as item>
    <#assign myObjectKey = item.getKey()/>
    <#assign myObjectValue = item.getValue()/>
    [...]
</#list>

Ответ 6

Вы можете использовать одну кавычку для доступа к ключу, установленному в вашей программе Java.

Если вы установили Map на Java, как этот

Map<String,Object> hash = new HashMap<String,Object>();
hash.put("firstname", "a");
hash.put("lastname", "b");

Map<String,Object> map = new HashMap<String,Object>();
map.put("hash", hash);

Затем вы можете получить доступ к элементам "хэш" в Freemarker следующим образом:

${hash['firstname']}
${hash['lastname']}

Выход:

a
b